C语言 数组和指针

本文详细解释了数组在内存中的存储结构,声明数组的方法,以及如何使用指针访问数组元素。重点强调了指针与数组的关系,指针仅识别地址和字节移动,而不自知数组范围。
摘要由CSDN通过智能技术生成

数组表示多个相同类型的元素的有序集合,数组在内存中是连续分布的,因此,使用指针运算读取元素非常快。

声明数组需要定义元素的类型,然后将数组名称后面加上中括号,中括号里面可以写上数组的最大长度,也可以不写,不过,最佳实践是永远都写上最大长度。等号右边将元素用花括号包裹,逗号隔开:

int arr[3] = {1,2,3};

实际元素的数量可以少于定义的长度,但是不能超过定义的长度。

数组名称是一个指针类型,指向数组的第一个元素的地址,也叫数组的首地址:

int arr[3] = {1,2,3};
printf("first element address: %p \n", &arr[0]);
printf("%p",  arr);

通过输出的结果可以看到,arr的值是一个地址,与数组首地址&arr[0]是相同的。

数组名是一个指针,如果该指针加1,表示该指针向后移动一个元素类型所占字节的长度,也就是跳到下一个元素,例如本例中,元素类型是int,占4个字节,所以向后移动了4个字节,刚好跳到了下一个元素的位置。

在下述代码中,定义了一个指针p,并将数组名称赋给它。此时p指向第一个元素,之后p++,此时p跳到了下一个元素。分别用p和*p打印除了此时的地址及值:

int arr[3] = {1,2,3};
int * p = arr;
printf("first address: %p \n", p);
printf("first address: %p \n", &arr[0]);
printf("first value: %d \n", *p);
printf("first value: %d \n", arr[0]);
p++;
printf("second address: %p \n", p);
printf("second address: %p \n", &arr[1]);
printf("second value: %d \n", *p);
printf("second value: %d \n", arr[1]);
p++;
printf("thrid address: %p \n", p);
printf("thrid address: %p \n", &arr[2]);
printf("third value: %d \n", *p);
printf("third value: %d \n", arr[2]);

输出结果如下:

first address: 0x7ffdb1610e80 
first address: 0x7ffdb1610e80 
first value: 1 
first value: 1 
second address: 0x7ffdb1610e84 
second address: 0x7ffdb1610e84 
second value: 2 
second value: 2 
thrid address: 0x7ffdb1610e88 
thrid address: 0x7ffdb1610e88 
third value: 3 
third value: 3 

根据结果可以得知,每次指针加1,地址就加了4个字节,刚好是整数类型所需的字节数。同时,使用*p读取元素值,和使用arr[1]读取元素值是等价的。

请注意,指针p并不知道自己指向的是数组的某个元素,还是一个独立的整数,它只知道自己指向了一个存储整型数据的内存地址而已。运行p++,它也只是按照数据类型移动了4个字节而已,它也并不知道移到了下一个元素,只是因为数组在内存中是连续分布的,指针的移动“刚好对上了”下一个元素的地址而已。总而言之,指针不认识数组,只知道自己指向一个地址,然后根据指针运算规则移动一定的字节长度,然后取出值而已。

我们可以接着上面的代码,虽然上面已经移动到了最后一个元素的位置,但是仍然可以再继续移动:

p++;
printf("next address: %p \n", p);
printf("next value: %d \n", *p);

输出结果是:

thrid address: 0x7ffdb1610e8c 
third value: -1025609304 

可以看到,指针依然移动了4个字节,依然读取了内存中的值,但这个值是没有意义的,它也不知道自己是否还处于数组所在的内存区域中。

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值