11、structure
结构体可以用{expression,expression,...}或者{.name=expression,.name=expression}来进行初始化
例如:
struct complex_struct z1 = { x, 4.0, };
但是{}本身不是expression,不能对struct进行赋值!
以下用法是错误的:
struct complex_struct z1; z1 = { 3.0, 4.0 };
C99增加了对一种语法如下,但是VC9中不支持这种语法,因此应该尽量避免采用。
struct complex_struct z1; z1 = (struct complex_struct) { 3.0, 4.0 };
结构体的成员名和变量名不在同一命名空间中,因此两者不会出现明明冲突。
另外,结构体可以相互赋值和初始化,但是无法进行==运算。
12、tip on left
由.运算符组成的表达式能不能做左值取决于.运算符左边的表达式能不能做左值。在上面的例子中,z
是一个变量,可以做左值,因此表达式z.x
也可以做左值,但表达式add_complex(z, z).x
只能做右值而不能做左值,因为表达式add_complex(z, z)
不能做左值。
13、enum
枚举类型的成员是整数常量,它们的值由编译器自动从0开始顺序分配,也可以自己指定每一个成员的常量值。如果只指定了部分成员的常量值的话,对于未赋值成员,编译器会从上一个赋值成员开始顺序累加。
成员的常量值是可以重复的,此时用这两个成员进行赋值的效果完全相同,对于取值分别为这两个成员的enum变量,程序认为他们是完全相等的。
typedef enum{PT1 = -1, PT2, PT3 = -2, PT4} pt;
以上代码中,PT4和PT1完全等价。
枚举的成员名和变量名在同一命名空间中,所以会出现命名冲突。
考虑以下来自<Linux C编程一站式学习>的代码,编译器是否会报错?是的话如何修正,不是的话运行结果如何?
#include <stdio.h> enum coordinate_type { RECTANGULAR = 1, POLAR }; int main(void) { int RECTANGULAR; printf("%d %d/n", RECTANGULAR, POLAR); return 0; }
14、Array
数组类型做右值使用时,自动转换成指向数组首元素的指针。
写代码时应尽可能避免硬编码。
C中数组采用Row-major存储,多维数组总是从最右边一个下标开始由0向上递增存储
15、Memberwise Initialization
用于对enum, struct, array中离散的个别元素进行初始化。
16、String
当一个字符型指针或字符型数组在定义的同时被用一个字符串初始化,那么这个字符串会被放到只读的数据段内。
即,如下代码:
char *str = "Try";
或
char str[] = "Try";
和如下代码:
const char str[] = "Try";
似乎是等价的,只是尝试对前者进行赋值的错误无法被编译器检查出来。
(这一点很奇怪,如果C标准规定了用字符串初始化时的行为,那么编译器为何不能检查出来?如果C标准并未这样定义,那么这些都是编译器自己的行为?)
另外,用字符串对int数组进行初始化的行为是不被gcc所支持的,但是在VC9中可以正常运作。被初始化的数组同样会被放到只读的数据段。