关于c中全局变量初始化

hhxx
  • 569

在《c程序设计语言》一书中看到一句话一直不太明白,说外部变量和静态变量的初始化表达式必须是常量表达式,可是在之后的章节中又看到这样的代码

#define ALLOCSIZE 10000
static char allocbuf[ALLOCSIZE];
static char *allcop = allocbuf;

求教这里面的allcop指针变量的初始化表达式为什么可以用?是因为数组名其实不是一个真正的变量吗?那数组名到底算什么呢?就是一个代表数组第一个元素的地址常量吗?再将数组改为一个指针变量以后也确实编译失败了,请问数组名到底是个什么存在呢?常量?

回复
阅读 5.6k
5 个回答

数组名其实可以理解成 char const *,
也就是 不能改变指向的指针,也就是 指针常量。。
全局类的指针,都要声明成const比较好

static char const * allcop = allocbuf;

数组是数组,指针是指针,二者是两回事。数组名在某些情况下可以隐式转换(或称作退化)为指向数组首个元素的指针。

例如,定义一个数组:

int a[10];

则数组a包含10个保存int类型变量的内存空间。你可以把任意一个int类型的变量赋值给a中的任一元素

a[4] = 2;  a[0] = 8;

而定义一个指针:

int *p;

则指针p包含1个保存int类型变量的地址的内存空间,不能直接保存int类型变量。你可以把任意一个int类型的变量的地址赋值给p

p = &a[4];  p = &a[0];

这两个例子很好理解,我们把数组a中下标为4或0的元素的地址赋值给了指针p。再看一个例子

p = a;   // (1) 正确
p = &a;  // (2) 错误

在语句(1)中,当我们直接使用数组名a来进行赋值的时候,数组名到指针的隐式转换(退化)发生了,此时数组名a退化成了这个数组的首个元素的地址(即&a[0]),它的类型退化成了int *。所以语句(1)的效果与上一个例子中的p = &a[0];相同。

在语句(2)中,&a并不会发生数组名到指针的隐式转换(退化),它返回的类型实际上是int (*)[10],并不会自动退化成int *,所以语句(2)的赋值是错误的。


另一个不会发生数组名到指针的隐式转换(退化)的例子是sizeof

  • sizeof(a)表示数组a的大小,即10 * sizeof(int)

  • sizeof(a[0])sizeof(*a)表示数组a中一个元素的大小,即sizeof(int)(注意在sizeof(*a)中发生了数组名到指针的退化。)

上面的回答已经说过此处数组名隐式转换为指向数组的指针,也就是赋给变量的是数组的地址。因为数组的地址在编译阶段就可以确定了,所以可以算是常量。

其实我只想说推荐看一下《C专家编程》里面关于数组和指针的部分,以及左值和右值的定义,看了这些之后我感觉对数组和指针就理解得比较清楚了。

数组名当右值使用时,是指针常量,指向数组首元素。 如:printf("%c", *allocbuf)
数组名当左值使用时(左值代表一块内存空间),代表数组所在的那块内存空间。如:sizeof(allocbuf)

还有一点值得注意,由于C语言函数传参传的是值,因此把数组名当参数传过去时,会退化成指针。

C里面数组就是指针 一定要记住
也就是说 数组名 和 &数组名[0] 地址是一样的
数组名就是一个指针 指向自己第一个元素

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏