《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++;
相关推荐
猫猫的小茶馆1 小时前
【STM32】预分频因子(Prescaler)和重装载值(Reload Value)
c语言·stm32·单片机·嵌入式硬件·mcu·51单片机
JeffersonZU1 小时前
Linux/Unix文件IO(文件描述符、原子操作、文件数据结构、open、read、write、fcntl、dup)
linux·c语言·unix·gnu
智者知已应修善业5 小时前
【51单片机用数码管显示流水灯的种类是按钮控制数码管加一和流水灯】2022-6-14
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
Alfred king11 小时前
面试150 生命游戏
leetcode·游戏·面试·数组
森焱森15 小时前
无人机三轴稳定控制(2)____根据目标俯仰角,实现俯仰稳定化控制,计算出升降舵输出
c语言·单片机·算法·架构·无人机
小林C语言17 小时前
C语言 | 判断是否为回文数
c语言
myloveasuka20 小时前
信号操作集函数
linux·运维·服务器·c语言·c++·vscode
Mr_Xuhhh21 小时前
网络基础(1)
c语言·开发语言·网络·c++·qt·算法
双叶83611 天前
(C语言)Map数组的实现(数据结构)(链表)(指针)
c语言·数据结构·c++·算法·链表·哈希算法
不会kao代码的小白11 天前
C指针总结复习(结合deepseek)
c语言