zoukankan      html  css  js  c++  java
  • step1.day12 Linux下使用C语言编程基础总结

    一:系统准备

    1.VMware软件安装,用来在现在操作系统下模拟Linux系统而不必重装系统

    2.Linux系统安装,推荐使用Ubuntu14.02版本,较为稳定
    注意:安装步骤,选择稍后安装虚拟机,完成必要的配置步骤后添加镜像安装
    打开VMware workstations→在主页中选择“创建新的虚拟机”→典型→稍后安装系统→选择Linux系统及版本→
    选择安装名称和路径→指定硬盘大小→自定义硬件配置→选择安装镜像→完成后启动此虚拟机开始安装→
    安装中按顺序要求填写用户名、语言、时区、管理员密码和创建用户等。

    建议选择已经配置好的系统,避免学习环境安装而浪费大量时间,且安装系统后的软件升级和配置需求很多其他知识,需要循序渐进
    下载配置好的系统,在虚拟机中选择打开虚拟机,选择文件夹后双击.Ubuntu.vmx后即可使用

    二、Linux系统下学习C语言的大致框架
    1.搭建环境、熟悉Linux下常用命令及vim编辑器
    2.C语言发展及基础知识,包含数据类型、变量、常量和运算符和优先级
    3.输入输出语句
    4.分支、循环语句(即控制语句)
    5.数组和字符串
    6.指针和数组即字符串
    7.函数。
    C语言的基础知识大致如此,编程语法和其他编程语言类似,逻辑思维能力需要多敲代码练习

    三、Linux系统的基础知识
    1.Linux是1991年由林纳斯托瓦斯创建,Linux内核具备以下5种功能①设备管理②文件管理③进程管理④内存管理⑤网络管理
    2.Linux文件系统和Windows不同,Linux的层级目录是通过文件系统组织管理,是倒置树结构,没有盘符感念,一切皆文件。
    3.Linux文件系统各个目录功能根据FHS(filesystem hierarchy standar)
    / 根目录
    /bin 用户命令和二进制文件
    /sbin 系统二进制文件
    /boot 系统启动相关文件
    /etc 系统启动时候用到的配置文件
    /dev 设备文件(通过此文件访问设备驱动)
    /home 用户家目录
    /lib 可执行程序需要连接的库文件
    /mnt/hgfs/share 共享目录

    4. shell命令

    Linux @ Ubuntu : ~
    用户名 间隔符 主机名 间隔符 家目录
    whoami 查看用户名
    hostnamec 查看主机名
    $ 符号表示普通用户
    #符号表示超级用户

    su root 从普通用户切换到root超级用户,输入密码不会显示
    sudo passwd root 进行修改超级用户密码

    exit 从root退回去Linux用户或退出terminal
    用户界面下打开terminal Ctrl+alt+T
    terminal状态下打开多个terminal Ctrl+shift+n
    ①ls命令
    ls 显示当前目录文件列表
    ls -l 查看文件属性(ll)
    ls -a查看所有文件包含隐藏文件(以. .. 开头文件)
    ls -lh 把文件大小转换为响应数量级
    ls -R 递归显示文件(文件下文件目录)
    ls -i 显示文件的iNode号

    文件类型: b s p - l c d
    块设备驱动文件 套接字文件 管道文件 普通文件 连接文件 字符设备驱动文件 目录文件
    权限: rwx rwx r-x (r 4 读 w 2 写 x 1 执行)
    用户 组 其他用户
    ls -l下 数值(如果是目录,代表子目录个数,如果是文件,代表副本个数)

    ②cd 命令 切换目录
    cd 相对路径/绝对路径
    cd cd~ 回到家目录
    cd - 回到上一次操作目录
    cd ../ 返回上一级目录 cd ../ ../返回上上级目录
    cd /mnt/hgfs 以绝对路径方式切换目录

    ③pwd 显示当前工作路径
    ④clear 清屏命令(实际是翻页)Ctrl+l
    ⑤touch 穿件文件命令 touch hello.c
    文件不存在即是创建,存在即是修改时间戳
    ⑥mkdir 创建目录
    mkdir hello 创建hello目录
    mkdir -m 0664 test 创建一个权限为664的目录
    cd test失败的原因可能是test/: Permission denied
    mkdir -p hello/test 递归创建目录及子目录

    ⑦rm 删除命令
    rm 文件名 rm *.c *是通配符
    rm -rf 删除目录 -r递归删除 -f强制删除

    ⑧chmod 修改权限 chmod 0664 hello 修改hello文件的权限为664
    ⑨cp 拷贝命令
    cp hello.c hello/ 拷贝hello.c文件到hello目录下
    cp hello/ test/ -r (-a)拷贝目录
    ⑩mv 移动或者重命名
    mv hello/ test/ 移动hello目录到hello目录下,如果没有权限 mv前+sudo(cd前不能+sudu,需切换至root后cd)
    mv hello.c hello1.c 重命名
    ⑪ echo 打印
    echo 1111 向屏幕终端打印1111
    echo 1111 >test.c 向test.c文件中写入1111(重定向,覆盖之前内容)
    echo 1111 >>test,c 向test.c文件中追加写入1111(不覆盖,追加写入)
    ⑫ cat 1.c 将1.c文件的内容在终端上显示

    5.vim编辑器命令
    在terminal终端上键入vi test.c,即创建一个test.c的文件,如果文件存在则是打开

    ①命令行模式 下的命令
    按Esc进入命令行: yy 拷贝
    nyy 拷贝n行
    dd 剪切
    ndd 剪切n行
    p 粘贴
    u 撤销
    gg=G 对其(或者鼠标左键选择后按=)
    /要查找的字符 查找字符串
    /^要查找的字符 查找字符串并高亮每行第一次出现的位置
    /字符串$ 查找字符串 显示并高亮每行以这个字符串结尾的位置
    n 下一个
    N上一个
    底行模式下 :nohl 取消高亮
    插入模式:按a 光标当前位置后插入 A 光标当前行位插入
    i 光标当前位置插入 I 光标当前行首插入
    o 当前位置下一行插入行 O 光标挡墙行上插入行
    底行模式 按空格或者:进入,
    :w 保存
    :wq 保存并退出
    :x 保存并退出
    :wqa 保存并退出所有
    :q 退出未修改文件
    :q! 强制退出
    :n 跳转到N行
    :nohl 取消高亮
    :set nu 显示行号
    :set nonu 取消显示行号
    :set mouse= 可以拷贝(按住shift鼠标选中后右键可拷贝)
    :set mouse=a 取消拷贝
    :60,65y 起止行号拷贝 剪切等
    :%s/旧/新/g 替换所有行
    :vsp 1.c 垂直现在文件打开另一个1.c
    :sp 1.c 水平现在文件打开另一个1.c

    二、C语言基础知识
    编程即是内存申请、内存管理和内存应用的过程
    1.一个hello world 程序
    #include <stdio.h> //包含printf的头文件
    // <> 在系统的/usr/include下找头文件
    // "" 在当前目录下找头文件
    int main()//c代码的入口函数
    {
    printf("hello world "); //printf是一个打印函数, 1.换行 2.刷新缓冲区域
    return 0;
    }

    编译代码分四步
    1.预处理:头文件展开、宏替换 gcc -E hello.c -o hello.i 不可执行
    2.编译:将预处理后文件生产汇编文件 gcc -S hello.i -o hello.s 不可执行
    3.汇编:将编译文件生产可执行文件 gcc -C hello.s -o hello.o 可执行但没有库文件
    4.连接:将c代码中用到的库文件连接到可执行程序中 可以执行

    2.计算机的组成(输入输出设备、控制器、运算器、存储设备、总线)
    哈佛结构:指令和数据分开存储的架构,效率高 常用DSP ARM
    冯诺依曼结构:指令和数据不分开存储、分时操作,效率低一些,用于早起的x86架构处理器

    3.存储器的类型
    ①cache 高速缓存(i-cache指令缓存 d-cache数据缓存)
    ②iROM 只读存储器(可存储可执行存放启动代码)
    ③IRAM 随机存储器 可执行掉电丢失数据
    ④DRAM/DDR 内存 可执行掉电丢失数据
    ⑤flash 硬盘
    Nor flash Nand flash Emmc 机械硬盘

    4.数据表示(计算机内只能以0 1 形式存储数据)
    进制:二进制0b 八进制 0 十进制 十六进制0x (几进制就是逢几进一),进制的相互转换(8进制占3位,16进制占四位转换)
    计算机中,数据以补码形式储存,正数源码反码补码一致,负数源码最高位是符号位,反码除符号位其他翻转,补码是反码+1
    补码的补码是源码 -128 10000000(特殊记住)
    1bit
    1byte = 8bit
    1KB =1024byte
    1M =1024kb
    1G =1024Mb
    1T =1024Gb
    1Pb =1024Tb
    5 .字符:根据ASCII表,不同字符有对应的0~255编码,特殊字符如‘a’‘A’‘0’''等
    6.C语言中的数据类型
    ①基本类型
    字符 char unsigned char 1字节
    整形 short (2字节) int(4字节) long(4字节) long long(8字节)
    实型 float(4字节) double(4字节) long double(12字节)
    枚举 enum

    ②构造类型:数组 结构体 共用体

    ③指针类型

    ④空类型 void

    注意:数据类型间可以强制转换,但是可能存在损失精度的风险,一般不转化
    大端小端问题:定义一个int类型,强制转换为char类型,取出的数值是高位是小端,取出的是低位是大段
    大端:高位存在低字节
    小端:高位存在高字节


    7.C语言中的变量声明(内存申请)
    <储存类型><变量类型><变量名>
    存储类型:auto register static const volatile extern
    变量类型即是数据类型
    变量名:①以字母数组下划线组成,且以字母或者下划线开头
    ②:不能是32个关键字
    ③ 大小写区分
    ④见名知意

    8.C语言中的常量
    ①.整形常量
    ②实型常量
    ③字符常量
    ④字符串常量
    ⑤标识常量 define(宏)
    #define M 5+1 预处理阶段原样展开。不计算
    #define S(a) #a 字符串化
    #define S(a,b) a##b 字符串拼接

    9.c语言中的运算符
    ()在前,单算移关与,异或逻条赋,逗号(按照优先级)
    注意:使用异或(加法)可以在不定义新的变量下 实现数值交换
    a^=b
    b^=a
    a^=b
    a=a+b
    b=a-b
    a=a-b
    注意:使用移位和或运算,实现高低位翻转(偶数位与1,左移一位 | 奇数位与1 右移1位),相邻一位对调 2位对调 4位对调
    条件运算符?: a>b?a:b

    10.C语言中的输入输出语句
    ①printf 格式化输出 %d %s %u %p %o %x %c %e %g %# %f %lf
    %4d 打印数占4个字符单元 前面补空
    %04d 打印数占4个字符单元,前面补0
    %-4d 左对齐
    %ld long
    %ld double
    %.2f 显示小数点后两位
    %Lf long double

    ②scanf
    scanf("%d%c%s%f",&a,&b,&c,&d);
    scanf("%d",&a);
    scanf("%c",&b);
    1.scanf在使用的时候它不会读取最后一个 的字符,可以使用%*c来吃掉一个字符。
    2.scanf如果需要连续输入两个(多个)整数,scanf("%d%d",&a,&b); 它会吃掉空格,回车,tab
    3.scanf双引号是什么格式,终端输入就是什么格式,scanf("%d,%d",&a,&b); -->1231,123
    4.scanf在连续输入的时候,它会把空格,tab,回车作为结束,如果不想以空格或tab作为结束,
    scanf("%[^ ]",c) //只把 作为结束符,可以读取 之外的所有字符
    5.如果scanf按照如下方式来实现
    scanf("%d ",&a);
    printf("%d ",a);
    scanf("%d ",&a);
    printf("%d ",a);
    scanf("%d ",&a);
    printf("%d ",a);
    输入一个整数之后,在额外输入一个字符(任意的),它就会结束了

    ③getchar
    函数原型:int getchar(void);
    功能:输入一个字符
    参数:@ 无;
    返回值:成功返回字符的ascii,失败返回-1;
    1.getchar的用法
    char a;
    a = getchar();
    printf("%c ",a);
    2.getchar吃掉字符
    int a;
    char b;
    scanf("%d",&a)
    b = getchar();

    3.在函数内部定义的变量默认是随机值,全局变量默认的值是0;

    ④putchar()
    函数原型:int putchar(int c);
    功能:输出一个字符
    参数:@c:想要输出的字符(ascii)
    返回值:成功返回字符的ascii,失败返回-1;
    一般用法:
    putchar(a);
    putchar(' ');
    putchar('A');
    putchar(' ');
    putchar(65);
    putchar(' ');

    ⑤gets()
    函数原型:gets(char *s);
    功能:读取多个字符
    参数:@s 数组的名字
    注意:
    gets会将缓冲区中所有的字符全部读入,不管内存是否越界。
    gets会在最后的位置补充
    char a[50];
    gets(a);

    ⑥puts()
    函数原型:int puts(const char *s);
    功能:输出多个字符
    参数:@s 数组的名字
    注意:puts只能用于输出多个字符(字符串),puts会自动补充

    用法:
    char a[50];
    puts(a);
    puts("hello world");
    puts(""); ---->自动输出一个换行

    area.c:(.text+0x130): undefined reference to `sqrt'
    collect2: ld returned 1 exit status
    该错误是未有链接文件,需gcc area.c -lm


    注意,自行定义的头文件格式位.h文件
    #ifndef __HEAD_H__
    #define __HEAD_H__

    int add(int a,int b);

    #endif


    11.C语言中的控制语言

    ①if 、if/else 、if/elseif........
    ②switch/case/default(case语句执行到遇到break,没有break则执行到最后,default语言在case都不执行时候执行,也是遇到break或到最后 )
    ③循环for(语句1;语句2;语句3),循环三要素 初始条件 判断条件 结束条件
    for循环执行顺序为,语句1,语句2,循环体,语句3,语句2.。。。。。。
    while()先判断后执行
    do while 先执行后判断
    ④continue 结束本次循环进行下一次循环,break,结束当前循环体
    ⑤goto 无条件跳转语言,只能在本函数内部跳转,需要一个标签(一般最为错误的统一处理口)
    ⑥return 结束函数或将行数返回值返回给调用者


    12.C语言中的数组

    ①.数组为构造类型,是基本类型的多个元素组合
    ②.数组内元素数据类型必须一致
    ③.数组在内存上连续
    ④.数组不进行越界检查
    ⑤.数组名是数组首地址(a+1 &a+1 &a[0]+1,移动步长为对应类型大小)杜绝a++ ,可以a+1
    char a[5],方括号内必须是常量
    ⑥数组赋值:①初始全部赋值,部分赋值(未赋值元素为0,)
    ②数组大小根据赋值数确定大小int a[] = {1,2,3,4}
    先定义后赋值需要借助循环赋值
    sizeof函数可以测量数组长度 sizeof(a)/sizeof(a[0])
    ⑦冒泡排序
    for(i=0;i<N-1;i++)
    for(j=0;j<N-i-1;i++)
    ⑧选择排序:记录最小或者最大值的下标,下标变了才交换

    a[-1],是数组前一个元素,不定值,不建议使用,数组不进行越界检查

    ⑨.二维数组 行号可以省略,列不可省略,二维数组名字也是常量,也不可a++
    ⑩.一维字符数组(以‘’结束就是字符串数组,字符串数组可以%s输入或者输出)
    ⑪.二维字符串数组,字符串的集合

    13 C语言中的指针
    地址:在计算机中,地址是以字节为单位进行编号,管理内存,每一个内存区域都有一个编号,这个编号叫做地址
    指针:指针就是指向地址的
    指针变量:存放地址的变量就叫做指针变量

    内存分类:
    ①堆区:需要手动申请和释放(malloc/free函数)
    ②栈区:用户的函数、局部变量,是由操作系统自行申请和释放的
    ③.bss:全局未初始化的变量以及static修饰的变量
    ④.data:存放用户的数据
    ⑤.ro:存放字符串常量
    ⑥。text:文本段

    1.指针的定义 :<存储类型><数据类型>*<变量名>
    char *p;
    short *t;
    int *q; //*这里的*是一个标识符,//代表定义的是指针类型的变量

    sizeof(char *); //4 p+1 移动1字节
    sizeof(int *); //4 q+1 移动4字节
    sizeof(short *);//4 t+1 移动2字节
    指针均占4个字节,指针加1,移动相应数据类型步长

    2.和指针相关的符号
    * //取出地址中的内容
    & //取地址符

    3.一维数组和指针
    int a[3];
    int *p = a;
    数组访问:a[i] <=====>p[i] <====> *(a+i) <====>*(p+i)
    注意:
    p++ //可以
    a++ //不行,原因a是数组名,它是常量不能做加减操作。

    4.指针和字符串
    char *p = "hello world"; 定义一个指针,指向字符串常量,*p内容不可以修改
    *p = 'a'; //错误的
    p++; //可以

    char buf[] = "hello world"; //在栈上存放
    char *a;
    char str[];

    buf[0] = 'a' //可以
    buf++; //错误的
    a = "hello world"; //可以
    str = "hello world";//错误

    5.指针和二维数组,
    注意:将数组名赋值给一级指针时候报错,类型不匹配,需要将数组名赋值给 (同步长数组指针)

    6指针数组:int *p[3],一个数组,数组元素为指针
    7.二级指针:指向一级指针的指针,通常用着传参函数中的套用函数传参
    8.数组指针 int (*p)[3] 它是一个指针,指向的是一个数组。这个数组(每一行有三个成员)
    数组指针和二维数组和相互对应的。数组指针和二维数组相对对应
    int a[3][3] = {1,2,3,4,5,6,7,8,9};
    int (*p)[3];
    p = a;
    a[i][j]<====>*(a[i]+j)<=====>*(*(a+i)+j)<======>
    p[i][j]<====>*(p[i]+j)<=====>*(*(p+i)+j)
    a+1 //移动一行,3(一行的成员个数)* sizeof(int)
    &a[i]+1 //移动一行,3(一行的成员个数)* sizeof(int)
    &a+1 //移动整个数组,3(三行)*3(一行的成员个数)* sizeof(int)
    a[i]+1 //移动一个成员的大小,sizeof(int);
    &a[0][0]+1 //移动一个成员的大小,sizeof(int);

    9.sizeof和strlen的区别
    1.sizeof是关键字,strlen是函数。
    2.sizeof可以求类型的大小,strlen求字符串成员的个数
    3.sizeof(buf) = 10(不包含''); strlen(buf) = 5(数组长度);


    14.C语言中的数据存储类型
    定义变量
    <存储类型> <变量类型><变量名>;

    auto :自动 auto int a;
    定义局部变量的时候,int a;前面其实是省略了auto。
    当函数执行的时候变量会被申请,当函数执行完的时候
    变量会被销毁。

    非自动类型的变量:全局变量或者static修饰的变量。
    static :1.延长变量的生命周期
    void swap()
    {
    static int a=3; //int a=3;
    printf("%d ",a++);
    }
    2.限制作用域(只能在本文件内使用)
    static int a;
    static void hello()
    {
    printf("hello");
    }

    register :寄存器
    register int a = 5;
    定义寄存器类型的变量,但是由于芯片内部的寄存器的个数是有限制的。
    所以在使用的时候注意使用的次数。寄存器类型的变量要比普通的变量
    读写的效率高。

    extern :外部的,可以在其他文件中调用
    extern int a;
    extern int add(int a,int b);

    const :它修饰的是一个只读的变量,修饰的不是常量。
    const int a = 5;
    a = 100; =>error: assignment of read-only variable ‘a’

    const char *p; => const *p; //p指向的内容不可修改
    char const *p; => const *p; //p指向的内容不可修改
    char * const p;=> const p; //p指向的地址不可以修改
    const char *const p; //指向的地址和内容都不可修改
    char const *const p; //指向的地址和内容都不可修改

    注意:把数据类型去掉后,const修饰的是谁,它就是一个只读的。

    volatile :字面含义(易变的)
    (volatile unsgined int *)0x50000000
    假如刚开始0x50000000中保存的是0x12345678;

    如果这里不加volatile,编译会对其进行优化,下代码中只要用到
    0x50000000地址中的值的时候,它取得都是0x12345678这个值。但是
    在操作系统运行的时候,可能会去修改0x50000000地址中的值。代码
    是不能取出到最新值的。

    volatile告诉编译器不对代码进行优化,每次在用这个地址中的值的
    时候,都要重新从这个地址中来取数据,所以加了volatile之后就能保证
    取到的都是最新的数据。

    15.C语言中的函数(函数是c语言最基本的组成单元)
    函数就是一个实现特定功能的代码集合,函数封装要遵从高内聚低耦合
    函数三要素:①功能唯一 ②输入 ③输出
    函数类型
    <存储类型><返回值类型><函数的名字>(参数列表)
    {
    语句;
    return;
    }

    注意:函数的使用要:先声明后使用,先使用的先声明
    函数的参数:
    1.参数的成员的个数一般小于等于4(效率高)
    2.函数的中的参数的名字叫做形式参数,形式参数(函数内部的变量)当函数被调用的时候分配内存,在函数执行结束的时候,形参所占的内存
    就会被释放。
    3.实参数:在main中定义的变量,int a = 5; int b =100 =>a就是实参,add(a,b);实际参数可以的变量,常量,表达式,地址。
    参数传递分为:
    值传递:不可以交换数据
    地址传递:可以交换数据
    传递数据:不是将整个数据都传递过去了,它是将数据的首地址传递过去了。
    传递数组:
    int func(int buf[100],int n)
    {
    sizeof(buf);
    }
    传递的是数组的首地址,在函数中sizeof(buf) == 4;
    传递函数:传递的是函数的首地址
    int func(int (*fn)(int ));
    int func(int fn(int ));

    函数使用中,会用到嵌套函数(函数内部调用其他函数)
    递归函数(自己调用自己)
    指针函数(返回值是指针的函数)
    函数指针(即函数名) int (*p)(int a, int b)
    函数指针数组(数组元素是函数指针的数组) int(*p[3])(int a, int b)
    函数指针数组指针:是一个指针,这个指针指向函数指针数组


    16 typedef 关键字 类型重命名,定义变量时候,将变量名去掉,改为想定义的名称即可
    typedef int INT_32; int
    typedef int INT_ARR[3]; int a[]
    typedef int INT_ARR_2[3][2]; int a[][]

    typedef int * INT_P; int *p
    typedef int * INT_A[3]; int *p[3]
    typedef int (*ARR_P)[3]; int (*p)[3]
    typedef int FUNC (int a,int b);
    typedef int (*FUNC_P)(int a,int b);

    添加新的知识点:1.float和double类型数据不能判断是否等于0(根据float的存储方式,永远不等于0)

                                  2、#define PI 3.1415   这里的PI是文本替换,是(字符串类型而非常量)

  • 相关阅读:
    GlusterFS 配置及使用
    zabbix-监控Linux服务器
    ansible安装及使用
    使用ansible 完成yum安装lamp环境
    mysql基础
    shell基础
    shell
    Javascript动画效果(四)
    Javascript动画效果(三)
    Javascript动画效果(二)
  • 原文地址:https://www.cnblogs.com/huiji12321/p/11153752.html
Copyright © 2011-2022 走看看