1. 数组赋值时不可以简单的使用“=”。例如:
char a[2][20] ;
a[1]="hello";
这是错误的。C语言把这语句解释为一个指针与另一个指针之间的(非法的)赋值运算。
但是在初始化时,
char a[2][20]={"hello"};
是允许的。对于字符串数组,可以使用
//法1
char * strs[2];
strs[1] = "hello";
//法2
char 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. 输入函数
scanf函数
返回值:scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF。
- 可以在格式化字符串中的”%”各格式化规定符之间加入一个整数,表示任何读操作中的最大位数。
- scanf()函数中没有精度控制。
如: scanf(“%5.2f”,&a); 是非法的。不能企图用此语句输入小数为2位的实数。 - 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔则可用空格,TAB或回车作间隔。
C编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。 - 在输入字符数据(%c)时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。包括间隔字符(空格等)
- 格式符为%s时,则如果输入数据出现空格或者换行符都会被当做结束符
- scanf函数第二个参数为变量地址,切记
getchar和getch函数
返回值:*getchar和getch函数返回值是用户输入的第一个字符的ASCII码*,如出错返回-1
- getchar和getch的区别:
- 获取用户输入的时机不同
- 获取用户输入的时机不同
当程序调用getchar时.程序就等着用户按键.用户输入的字符被存放在键盘缓冲区中.直到用户按回车为止(回 车字符也放在缓冲区中).当用户键入回车之后,getchar才开始从stdin流中每次读入一个字符.
getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回- getchar和getch的区别:
- 函数执行后结果不同
- 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);
结果将会打印
S String
因为
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