鱼C论坛

 找回密码
 立即注册
查看: 2261|回复: 5

能解释的更通俗易懂点么

[复制链接]
发表于 2020-4-11 10:53:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 如果孤独感 于 2020-4-11 11:28 编辑

当一个数组名出现在一个表达式中时,它会被转换为指向该数组第一个元素的指针常量,既然是常量,那么对它进行 & 操作,似乎会有问题。

复制代码
1 void main ()
2 {
3     int ary[5] = {1, 2, 3, 4, 5};
4
5     printf("%p\r\n", ary);
6     printf("%p\r\n", &ary);
7 }
复制代码
编译,运行,一切都很正常。我们都知道,& 操作符的操作对象必须是左值,为什么可以对一个常量进行 & 操作呢?

可以通过下面这段代码,验证 ary 是一个常量

复制代码
1 void main ()
2 {
3     int ary[5] = {1, 2, 3, 4, 5};
4
5     printf("%p\r\n", ary);
6     ary++;
7 }
复制代码
编译报错:error C2105: '++' needs l-value

可以看到,ary 确实是一个常量,可它确实能进行 & 操作,这是怎么回事呢?正向退不出来,我们可以试一下反向推导。

复制代码
1 void main ()
2 {
3     int ary[2][3] = {
4         1, 2, 3,
5         4, 5, 6
6     };
7
8     printf("sizeof(ary) = %d\r\n", sizeof(ary));
9     printf("ary = %d\r\n", ary);
10
11     printf("sizeof(*ary) = %d\r\n", sizeof(*ary));
12     printf("*ary = %d\r\n", *ary);
13
14 }
复制代码
观察运行结果,ary = *ary, * 号是取指针内容,这个地址存放的内容是 1 ,怎么会相等呢?难道不是取地址内容的意思吗?

PS:* 号有三种含义,1、乘法;2、定义指针;3、取指针内容

那其他两种用法就更不靠谱了,难道是一种新的用法?

在观察,可以发现,sizeof(ary) != sizeof(*ary),他们分别是24和12,我们似乎发现了什么,24 = 2*3*4,12 = 3*4。



结论:当 * 号作用于数组名的时候,类型改变,而值不变,* 号表示解除引用的意思。有加法必有减法,同理,可以对数组名做 * 操作,那么就可以对数组名做 & 操作,表示改变地址的类型。这就可以解释,为什么可以对数组名这个常量进行 & 操作,值不变,类型发生变化。



总结:对数组名的 & 和 * 操作,值不变,指针升级或降级。
提问
为什么升级或降级后就可以了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-11 18:15:22 | 显示全部楼层
#include <stdio.h>
int main(void)
{
        static char arr[3][10];
        
        printf("指针(char*)arr + 1(整数)                                          sizeof(arr+1)         = %-2d\n",sizeof(arr+1));
        printf("解引用*(指针(char*)arr + 1(整数))                                 sizeof(*(arr+1))      = %-2d\n",sizeof(*(arr+1)));
        printf("指针(char*)(解引用*(指针(char*)arr + 1(整数))) + 0(整数)          sizeof(*(arr+1)+0)    = %-2d\n",sizeof(*(arr+1)+0));
        printf("解引用*(指针(char*)(解引用*(指针(char*)arr + 1(整数))) + 0(整数)) sizeof(*(*(arr+1)+0)) = %-2d\n",sizeof(*(*(arr+1)+0)));
    return 0;
}
指针(char*)arr + 1(整数)                                          sizeof(arr+1)         = 8
解引用*(指针(char*)arr + 1(整数))                                 sizeof(*(arr+1))      = 10
指针(char*)(解引用*(指针(char*)arr + 1(整数))) + 0(整数)          sizeof(*(arr+1)+0)    = 8
解引用*(指针(char*)(解引用*(指针(char*)arr + 1(整数))) + 0(整数)) sizeof(*(*(arr+1)+0)) = 1

--------------------------------
Process exited after 0.01299 seconds with return value 0
请按任意键继续. . .
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-11 21:00:57 | 显示全部楼层

升级或降级后不还是数组,不还是地址常量么??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-11 21:05:12 | 显示全部楼层
如果孤独感 发表于 2020-4-11 21:00
升级或降级后不还是数组,不还是地址常量么??

那是指针
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-12 08:34:59 | 显示全部楼层

话说arr不是代表arr【0】【0】么,为什么+1后还可以解引用,还可以两层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-12 08:35:35 | 显示全部楼层

数组就变成指针了??
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-15 06:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表