《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++;
相关推荐
小莞尔2 天前
【51单片机】【protues仿真】基于51单片机的篮球计时计分器系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小莞尔2 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
liujing102329292 天前
Day03_刷题niuke20250915
c语言
第七序章2 天前
【C++STL】list的详细用法和底层实现
c语言·c++·自然语言处理·list
l1t2 天前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
l1t3 天前
利用美团龙猫用libxml2编写XML转CSV文件C程序
xml·c语言·libxml2·解析器
Gu_shiwww3 天前
数据结构8——双向链表
c语言·数据结构·python·链表·小白初步
你怎么知道我是队长3 天前
C语言---循环结构
c语言·开发语言·算法
程序猿编码3 天前
基于 Linux 内核模块的字符设备 FIFO 驱动设计与实现解析(C/C++代码实现)
linux·c语言·c++·内核模块·fifo·字符设备
mark-puls3 天前
C语言打印爱心
c语言·开发语言·算法