表达式
表达式语句是表达式后加;
如hour * 60 + minute;
表达式有值和类型两个基本属性
等号运算符的计算结果是左边的值。多个等号从右到左计算。
如果一个操作数左右两侧各有一个相同优先级的运算符,这个操作数的结合取决于运算符的结合性,相同优先级的运算符的结合性相同。
a=b=c 合法 而(a=b)=c (a=b)不是左值 不合法
函数调用是一种表达式,()运算符是后缀运算符,函数名是操作数,()及其中参数是操作数的后缀
使用math.h加-lm
echo $?可以查看上一条命令的退出状态(return 0)
调用未声明的函数,编译器猜测类型,猜测返回值为int
调用函数时若参数列表为空,且缺乏函数原型,则编译器认为参数类型是void
声明函数时若参数列表为空,属于Old Style C,编译器认为参数类型和个数没有明确指定
//不允许嵌套定义函数
声明也是以;号结尾,这一点和语句类似,但是在语法上声明和语句是有区别的
switch坑
case 1: int i = 10;
switch(n) {
int i = 10;//i未初始化
case 1:
//...
}memberwise initialization
多维数组 或者结构体数组嵌套同理
struct complex z1 = {.y = 4.0};//z1.x=0.0 z1.y=4.0
int count[4]= {[2] = 3};枚举类型的成员名和变量名在同一空间,而结构体不在。
数组不能相互赋值,也就不能用作函数参数或返回值,但数组类型作右值时,会自动转换成指向数组首元素的指针。
字符串字面量的字符可以用下标访问但不能修改,字符串字面量作右值使用时也自动转换成指针
char c = "Hello, world"[1];c语言存储数组,一行一行拼成一串,row major
int a[3][2] = {1,2,3,4,5};-g选项生成文件才可以调试
gcc -g main.c -o main
gdb main
list //查看源代码
start //开始
next //一句句执行
step //进入
backtrace //查看栈帧
info local //查看变量
frame //选择栈帧
print 表达式//打印表达式的值
finish //运行到返回
set var 变量=xxx //
display //跟踪显示变量
break //设置断点
continue //运行到断点为止
info breakpoints
break 9 if sum != 0
run异或应用
从异或的真值表可以看出,不管是0还是1,和0做异或保持原值不变,和1做异或得到原值的相反值。可以利用这个特性配合掩码实现某些位的翻转
如果a 1 ^a 2 ^a 3 ^…^a n 的结果是1,则表示a 1 、a 2 、a 3 …a n 之中1的个数为奇数个,否则为偶数个。可用于奇偶校验
由于x^x=0 x^x^y=y 可用于交换变量
//不适用于a=b
*a = *a ^ *b;
*b = *b ^ *a;
*a = *a ^ *b;sizeof
sizeof是一个很特殊的运算符,它有两种形式:“sizeof 表达式”和“sizeof(类型名)”。
“sizeof 表达式”中的表达式不求值,只推断类型。编译时就能得到
int a[12];
printf("%u\n", sizeof a/sizeof a[0]); //48/4返回值类型为size_t,定义在stddef.h头文件中,是一种无符号整型
typedef
typedef char array_t[10];
array_t a;