相信很多小伙伴对C/C++语言中数组与指针的理解,如同阅读百年孤独一样对人名傻傻分不清,今天就来详细聊一聊令人头(tuo)疼(fa)的数组与指针。
数组名是什么?
数组名实际上就是数组首元素的地址信息,查看以下代码,
void test1(void)
{
int nums[4] = {1, 2, 3, 4};
printf("nums 的地址是: %p\n", nums);
printf("&nums[0] 的地址是: %p\n", &nums[0]);
return;
}
复制
运行结果如下,可以发现两者地址相同。
通过指针访问数组元素
当指针指向数组时,可以通过指针的加减运算,实现对数组元素的间接访问,查看以下代码,
void test2(void)
{
int nums[] = {1, 2, 3, 4, 5, 6, 7};
int *p = nums;
for(int i = 0; i < 7; i++){
printf("*(p + %d) = %d\tnums[%d] = %d\n", i, *(p + i), i, nums[i]);
printf("(p + %d) = %p\t&nums[%d] = %p\n", i, (p + i), i, &nums[i]);
}
return ;
}
复制
运行结果如下,需要特别注意的是,p+1并不是简单的将地址加1,而是加上sizeof(datatype)的距离。
指针与数组的区别
读完上面两小节,读者会发现数组与指针似乎一模一样,其实不然。
区别一:数组一经定义,数组名便是指向数组首元素的常量指针,而指向数组的指针则可以修改。
区别二:对数组名取sizeof,得到的是整个数组占用空间的大小,对指针取sizeof为固定值,32位机为4字节,64位机为8字节。
void test3(void)
{
int nums[] = {1, 2, 3, 4};
int *p = nums;
printf("sizeof nums = %ld\n", sizeof(nums));
printf("sizeof p = %ld\n", sizeof(p));
return ;
}
复制
运行上述代码,结果如下:
指针数组与数组指针
正确区别两者,可以从运算符优先级入手,由于下标运算符[]优先级高于取值运算符*,因此:
int *arr[4]; 指针数组
int (*arr)[4]; 数组指针
复制
指针数组本质上是数组,数组中每个元素为指针变量,请看如下代码:
void test4(void){
char *arr[4] = {"百年孤独", "没有人给他写信的上校",
"霍乱时期的爱情", "一场事先张扬的凶杀案"};
for(int i = 0; i < 4; ++i){
printf("arr + %d = %s\n", i, *(arr + i));
}
return ;
}
复制
运行结果如下:
数组指针本质上是指针,指向一个数组,请看如下代码:
void test5(void){
int nums[4] = {1, 2, 3, 4};
// int (*perr)[4] = nums;
int (*p)[4] = &nums;
for(int i = 0; i < 4; ++i){
// printf("%d\t", *(perr + i));
printf("%d\t", *(*p + i));
}
printf("\n");
return ;
}
复制
运行结果如下:
需要特别注意的是,代码上注释的两行并不能达到预期结果,这是因为perr本质上只是指向数组首元素的指针,并不是指向数组的指针,因此应该将数组名取地址再赋值给数组指针。
二维数组与指针
对于二维数组,同样可以利用指针进行访问,例如"int nums[3][4];",可进行如下转换:
查看如下代码:
void test6(void){
int nums[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7},
{8, 9, 10, 11}};
printf("nums = %p\n", nums);
printf("nums + 1 = %p\n\n", num + 1);
printf("nums + 1 = %p\n", num + 1);
printf("nums[1] = %p\n", nums + 1);
printf("&nums[1][0] = %p\n", &nums[1][0]);
printf("nums[1][0] = %d\n", nums[1][0]);
printf("*(nums + 1) = %d\n\n", *(nums + 1));
printf("*(nums + 2) + 3 = %p\n", *(nums + 2) + 3);
printf("&nums[2][3] = %p\n", &nums[2][3]);
printf("nums[2][3] = %d\n", nums[2][3]);
printf("*(*(num + 2) + 3) = %d\n", *(*(nums + 2) + 3));
return ;
}
复制
运行结果如下:
分析上述结果,可以发现对于二维数组 "int nums[M][N];",有:
nums + 1 = nums + sizeof(int) * N;
*(nums + i) = nums[i];
*(*(nums + i) + j) = nums[i][j];
复制
后记
讲完啦,欢迎大家勘误并提出修改意见,谢谢大家。
文章转载自Code小燕儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1190次阅读
2025-04-27 16:53:22
2025年3月国产数据库中标情况一览:TDSQL大单622万、GaussDB大单581万……
通讯员
866次阅读
2025-04-10 15:35:48
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
681次阅读
2025-04-30 15:24:06
数据库,没有关税却有壁垒
多明戈教你玩狼人杀
583次阅读
2025-04-11 09:38:42
天津市政府数据库框采结果公布,7家数据库产品入选!
通讯员
570次阅读
2025-04-10 12:32:35
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
548次阅读
2025-04-14 09:40:20
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
488次阅读
2025-04-17 17:02:24
一页概览:Oracle GoldenGate
甲骨文云技术
464次阅读
2025-04-30 12:17:56
GoldenDB数据库v7.2焕新发布,助力全行业数据库平滑替代
GoldenDB分布式数据库
457次阅读
2025-04-30 12:17:50
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
352次阅读
2025-04-18 10:01:22