《C和指针》笔记29:数组名和指针

看下面的代码

c 复制代码
int b[10];

b[4]的类型是整型,但b的类型又是什么?它所表示的又是什么?一个合乎逻辑的答案是它表示整个数组,但事实并非如此。在C中,在几乎所有使用数组名的表达式中,数组名的值是一个指针常量,也就是数组第1个元素的地址。它的类型取决于数组元素的类型:如果它们是int类型,那么数组名的类型就是"指向int的常量指针";如果它们是其他类型 ,那么数组名的类型就是"指向其他类型 的常量指针"。

不要根据这个事实得出数组和指针是相同的结论 。数组具有一些和指针完全不同的特征。例如,数组具有确定数量的元素,而指针只是一个标量值。编译器用数组名来记住这些属性。只有当数组名在表达式中使用时,编译器才会为它产生一个指针常量。

注意这个值是指针常量,而不是指针变量。你不能修改常量的值。你只要稍微回想一下,就会认为这个限制是合理的:指针常量所指向的是内存中数组的起始位置,如果修改这个指针常量,唯一可行的操作就是把整个数组移动到内存的其他位置。但是,在程序完成链接之后,内存中数组的位置是固定的,所以当程序运行时,再想移动数组就为时已晚了。因此,数组名的值是一个指针常量。

只有在两种场合下,数组名并不用指针常量来表示:

  1. 就是当数组名作为sizeof操作符或单目操作符&的操作数时。sizeof返回整个数组的长度,而不是指向数组的指针的长度。
  2. 取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量值的指针。
c 复制代码
int a[10];
int *c;
c = &a[0];

表达式&a[0]是一个指向数组第1个元素的指针。但那正是数组名本身的值,如果数组名表示整个数组,这条语句就表示整个数组被复制到一个新的数组。但事实上完全不是这样,实际被赋值的是一个指针的拷贝,c所指向的是数组的第1个元素。所以下面这条赋值语句和上面那条赋值语句所执行的任务是完全一样的:

c 复制代码
c = a;

像下面的语句是非法的:

c 复制代码
b = a;

因为不能使用赋值符把一个数组的所有元素复制到另一个数组。必须使用一个循环,每次复制一个元素。

下面这条语句:

c 复制代码
a = c;

c被声明为一个指针变量,这条语句看上去像是执行某种形式的指针赋值,把c的值复制给a。但这个赋值是非法的:记住!在这个表达式中,a的值是个常量,不能被修改。所以不能进行下面的操作:

c 复制代码
a++;
相关推荐
Y4090011 小时前
C语言转Java语言,相同与相异之处
java·c语言·开发语言·笔记
棐木9 小时前
【C语言】动态内存管理
c语言·free·malloc·realloc·calloc·动态内存
屁股割了还要学13 小时前
【C语言进阶】内存函数
c语言·开发语言·学习·算法·青少年编程
耳总是一颗苹果13 小时前
C语言---自定义类型(上)(结构体类型)
c语言·开发语言
basketball61617 小时前
Linux C 进程基本操作
linux·运维·服务器·c语言·后端
草莓熊Lotso18 小时前
【LeetCode刷题指南】--数组串联,合并两个有序数组,删除有序数组中的重复项
c语言·数据结构·其他·刷题
平哥努力学习ing18 小时前
C语言内存函数
c语言·开发语言·算法
wenke00a18 小时前
C函数实现strcopy strcat strcmp strstr
c语言·前端
慕洋男孩19 小时前
错误经验一:计算两个整数a和b的和
c语言·经验分享·错误经验
小xiao白21 小时前
不能使用枚举作为 宏定义的定义
c语言·ide·单片机·物联网