在讲自增、自减运算符时说++i
相当于i = i + 1
,其实更准确地说应该是等价于i += 1
,表达式只求值一次,而--i
等价于i -= 1
。
条件运算符(Conditional Operator)是C语言中唯一一个三目运算符(Ternary Operator),带三个操作数,它的形式是表达式1 ? 表达式2 : 表达式3
,这个运算符所组成的整个表达式的值等于表达式2或表达式3的值,取决于表达式1的值是否为真,可以把它想像成这样的函数:
表达式1相当于if
语句的控制表达式,因此它的值必须是标量类型,而表达式2和3相当于同一个函数在不同情况下的返回值,因此它们的类型要求一致,也要做Usual Arithmetic Conversion。
下面举个例子,定义一个函数求两个参数中较大的一个。
- int max(int a, int b)
- {
- return (a > b) ? a : b;
注意,函数调用时各实参之间也是用逗号隔开,这种逗号是分隔符而不是逗号运算符。但可以这样使用逗号运算符:
传给函数f
的参数有三个,其中第二个参数的值是表达式t+2
的值。
sizeof
是一个很特殊的运算符,它有两种形式:“sizeof 表达式”和“sizeof(类型名)”。这个运算符很特殊,“sizeof 表达式”中的子表达式并不求值,而只是根据类型转换规则求得子表达式的类型,然后把这种类型所占的字节数作为整个表达式的值。有些人喜欢写成“sizeof(表达式)”的形式也可以,这里的括号和return(1);
的括号一样,不起任何作用。但另外一种形式“sizeof(类型名)”的括号则是必须写的,整个表达式的值也是这种类型所占的字节数。
比如用sizeof
运算符求一个数组的长度:
- int a[12];
- printf("%d\n", sizeof a/sizeof a[0]);
sizeof
运算符的结果是size_t
类型的,这个类型定义在stddef.h
头文件中,不过你的代码中只要不出现size_t
这个类型名就不用包含这个头文件,比如像上面的例子就不用包含这个头文件。C标准规定size_t
是一种无符号整型,编译器可以用做一个类型声明:
那么size_t
就代表unsigned long
型。不同平台的编译器可能会根据自己平台的具体情况定义size_t
所代表的类型,比如有的平台定义为unsigned long
型,有的平台定义为unsigned long long
型,C标准规定size_t
这个名字就是为了隐藏这些细节,使代码具有可移植性。所以注意不要把size_t
类型和它所代表的真实类型混用,例如:
- unsigned long x;
- x = y;
如果在一种ILP32平台上定义size_t
代表unsigned long long
型,这段代码把y
赋给x
时就把高位截掉了,结果可能是错的。
typedef
这个关键字用于给某种类型起个新名字,比如上面的typedef
声明可以这么看:去掉typedef
就成了一个变量声明unsigned long size_t;
,size_t
是一个变量名,类型是unsigned long
,那么加上typedef
之后,size_t
就是一个类型名,就代表unsigned long
类型。再举个例子: