C语言查漏补缺

来源:互联网 发布:微场景模板制作软件 编辑:程序博客网 时间:2024/04/30 14:18

1. 数组赋值时不可以简单的使用“=”。例如:

char a[2][20] ; a[1]="hello";

这是错误的。C语言把这语句解释为一个指针与另一个指针之间的(非法的)赋值运算。
但是在初始化时,
char a[2][20]={"hello"};
是允许的。对于字符串数组,可以使用

//法1char * strs[2];strs[1] = "hello";//法2char strs[2][20];strcpy(&strs[1], "hello");

2. C语言运算符优先级。

1. 助记口诀

括号成员第一;
全体单目第二;
乘除余三,加减四;
移位五,关系六;
等于(与)不等排第七;
位与异或和位或,”三分天下”八九十;
逻辑或跟与,十二和十一;
条件高于赋值
逗号运算级最低

2. 结合性
结合性是指:

当一个运算对象两侧运算符的优先级别相同时, 运算对象与运算符的结合顺序。
例如a-b+c, b两侧有-和+两种运算符的优先级相同, 按先左后右结合方向, b 先与减号结合, 执行a- b 的运算, 再执行加c 的运算。

大多数运算符结合方向是“自左至右”, 即: 先左后右,
除了自左至右的结合性外, C 语言有三类运算符参与运算的结合方向是从右至左。即: 单目运算符, 条件运算符, 以及赋值运算符

3. 算数表达式计算顺序
1. 先比较优先级,优先级高者先行
2. 同优先级间按照结合性原则进行运算

3. break与continue

  • 有效性规则
    • continue只对直接包含它的循环体有效(也就是for,while, 而switch{}中的不算循环体);
    • break有效的是直接包含它的for,while,switch块。
  • 在不包含switch的代码中出现break或者continue,那么break跳出循环体,而continue跳出本次循环
  • 对于在循环中嵌套switch语句的代码中,break仅跳出最内层的块,这个块若是switch,就仅跳出switch,而continue即使出现在switch块中,因为continue的作用范围仅针对 for while 之类的循环语句,故不起作用,依旧跳出本次循环

4. 输入函数

  1. scanf函数

    返回值:scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF。

    1. 可以在格式化字符串中的”%”各格式化规定符之间加入一个整数,表示任何读操作中的最大位数
    2. scanf()函数中没有精度控制
      如: scanf(“%5.2f”,&a); 是非法的。不能企图用此语句输入小数为2位的实数。
    3. 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔则可用空格,TAB或回车作间隔。
      C编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。
    4. 在输入字符数据(%c)时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。包括间隔字符(空格等)
    5. 格式符为%s时,则如果输入数据出现空格或者换行符都会被当做结束符
    6. scanf函数第二个参数为变量地址,切记
  2. getchar和getch函数

    返回值:*getchar和getch函数返回值是用户输入的第一个字符的ASCII码*,如出错返回-1

    1. getchar和getch的区别:
      1. 获取用户输入的时机不同

    当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回 车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.
    getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回

  3. 函数执行后结果不同
    • getchar()执行后会打印函数返回值
    • getch()执行后不打印
  • getch()和getchar()可以用于循环获取用户输入。例如:
  • while((c=getchar())!='\n')putchar(c);
    3. 不能用getch()来接受缓冲区已存在的字符4. getch函数**不是标准C函数**,使用时注意移植性。详细参考[百度百科][url]

    3. ###gets函数
    函数原型
    char * gets ( char * str );
    返回值:
    读入成功,返回与参数buffer相同的指针;读入过程中遇到EOF(End-of-File)或发生错误,返回NULL指针。
    功能:
    gets从标准输入设备读字符串函数。可以无限读取,不会判断上限以回车结束读取,所以程序员应该确保buffer的空间足够大,以便在执行读操作时不发生溢出

    • C11标准中删除了 gets()函数,使用一个新的更安全的函数gets_s()替代

    5. switch语句的case 必须是常量且可以是常量算术表达式

    • 例如:
    switch(x){case 1+1: break;}

    6. 指针数组与数组指针

    1. 指针数组

    定义: int p[n];
    []优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。

    2. 数组指针(也称行指针)

    定义 int (*p)[n];
    ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。

    7.结构体与共用体

    结构体

    c语言中的结构体是指使用保留字struct开辟的一块内存。这块内存的大小是定义该结构体时的所有元素的空间和。
    1. 定义

    struct Struct{    char a;    char str[10];};

    2. 使用

    struct Struct s = {12, "string"};printf("%s",s.str);

    共用体

    c语言中的共用体是指使用保留字union开辟的一块内存。这块内存的大小取决于定义该union时的最大元素的长度。
    1. 定义

    union Union{    char a;    char str[10];};

    2. 使用

    union Union = {.str="string"};//注意: 共用体不能初始化。printf("%s",u.str);

    3. 共用体的存储方式
    共用体是以其子元素中空间占用最大的一个为大小的一块内存,共用体的指针是其所有子元素共同的首地址(也就是说,共用体中一次只能存放一个子元素)。每次赋值,都将会从共用体头指针开始,覆盖掉原数据进行赋值。
    在以下代码中:

    union Union{    char a;    char str[10];};union Union u;u.str = "string";u.a = 'S';printf("%c\\n",u.a);printf("%s",u.str);

    结果将会打印

    SString

    因为u.s在为u.a赋值时被覆盖了。"string"的前sizeof(u.a)个字符被覆盖为"S"
    4. 共用体本质是一块内存空间
    共用体本质上类似于malloc()开辟的一块内存空间(并不完全一致,因为malloc()开辟的空间在堆内存区)。所以可以使用指针来灵活操作共用体。

    union Union{    char a;    char str[10];};int main(){    union Union u = {.str="string"};    char * s;    s = (char *)&u;    s[0] = 'S';    printf("%s",a);}

    最终输出String。另外,由于使用指针s修改了共用体u,所以u.a的值为S

    原创粉丝点击