C语言中的对象必须有且只有一个定义,但它可以有多个extern声明。
(1)定义,只能出现在一个地方,确定对象的类型并分配内存,用于创建新的对象。例如
int my_array[100];
(2)声明,可以多次出现,描述对象的类型,用于指代其他地方定义的对象(例如在其他文件里)。
extern int my_array[];
extern对象声明告诉编译器对象的类型和名字,对象的内存分配则在别处进行。由于并未在声明中为数组分配内存,所以并不需要提供关于数组长度的信息。对于多维数组,需要提供除最左边一维之外其他维的长度,这就给编译器足够的信息产生相应的代码。
指针和数据的区别:
(1)数组元素的访问形式和指针访问形式不同。
(2)指针保存数据的地址,而数组保存数据。
(3)指针间接访问数据,首先取得指针的内容,把它作为地址,然后从这个地址提取数据。如果指针有一个下标[i],就把指针的内容加上i作为地址,从中提取数据。数组直接访问数据,a[i]只是简单地以a+i为地址取得数据。
(4)指针通常用于动态数据结构。数组通常用于存储固定数目且数据类型相同的元素。
(5)指针的相关函数为malloc和free。数组则隐式分配和删除。
(6)指针通常指向匿名数据。数据自身即为数据名。
数组和指针都可以在它们的定义中用字符串常量进行初始化。尽管看上去一样,底层的机制却不相同。
定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义时同时赋给指针一个字符串常量进行初始化。
注意只有对字符串常量才是如此,不能指望为浮点数之类的常量分配空间。例如:
float *pip = 3.14; // 错误
初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。与指针相反,由字符常量初始化的数组是可以修改的。例如:
strncpy(a, "black", 5);
专业的C程序员必须熟练掌握malloc函数,并且学会用指针操纵匿名内存。