理解C语言中的别名
我试图理解如何正确创建别名 我要给你下个定义 如果两个表达式具有相同的名称,则它们是彼此的别名 与它们关联的位置 下图是显示内存分配的方框图 目标是为理解C语言中的别名,c,C,我试图理解如何正确创建别名 我要给你下个定义 如果两个表达式具有相同的名称,则它们是彼此的别名 与它们关联的位置 下图是显示内存分配的方框图 目标是为a[1] 盒子的边缘是指位置,里面的圆圈是指存储的值 我发现b[1]有一个值,它是a[1]的地址。所以 我认为,为了创建别名,我所要做的就是创建一些变量,并将其赋值为b[1] 为了测试我的假设是否正确,我尝试了以下方法: struct T *alias = *b[2]; printf("alias location is: %p\n", ali
a[1]
盒子的边缘是指位置,里面的圆圈是指存储的值
我发现b[1]
有一个值,它是a[1]
的地址。所以
我认为,为了创建别名,我所要做的就是创建一些变量,并将其赋值为b[1]
为了测试我的假设是否正确,我尝试了以下方法:
struct T *alias = *b[2];
printf("alias location is: %p\n", alias);
printf("a[2] location is: %p\n", a[2]);
产生:
alias location is: 0x561936c62320
a[2] location is: 0x561936c62320
地址匹配,但我不知道我是否做对了。我不需要在printf()
函数中使用&
运算符来打印实际地址吗?当我这样做时:
struct T *alias = *b[2];
printf("alias location is: %p\n", &alias);
printf("a[2] location is: %p\n", &a[2]);
我的地址不正确:
alias location is: 0x7ffdee2cd320
a[2] location is: 0x7ffdee2cd340
有人能解释一下我做的是否正确,以及如何正确地做吗?对于
块语句
(例如,{…}
),(a)
考虑自动分配(或由于堆栈上的函数调用而发生的分配)和(b)
考虑用户分配(或由于结构
或联合
的大小而发生的分配):
在(a)
的情况下,对sizeof运算符
求和以确定堆栈分配的量
在(b)
的情况下,将运算符的大小
相乘,以确定阵列偏移的位置
需要注意的是,其他存储类可能会有不同的结果,但这些通常是您在使用C编程时最有经验的存储类。“别名”只是指一个替代名称。在C语言中,我们在“别名”的意思中所指的“名称”是左值。根据C 2018 6.3.2.1 1,“左值是一个表达式…可能指定一个对象…”如果同一事物有两个左值,则该事物有两个别名(或者您可以指定一个作为主要名称,另一个作为别名) 最简单的是,在
intb之后
,b
是由b
命名的对象的左值。在int*p=&b
,*p
是同一对象的左值。然后b
和*p
是同一对象的别名
您显示的图表的含义不清楚。它的一部分将a
和b
显示为简单的标量对象。另一部分将它们显示为数组。没有更多的上下文和解释,就不可能可靠地解释它
如果我们有一个
inta[1]
和一个intb[1]
,而编译器恰好在a
之后立即将b
放入内存,那么a[1]
在某种意义上是b[0]
的别名,但使用它是不恰当的,因为C标准中的规则没有定义越界访问数组的行为,即使我们不知怎么知道它在内存中是什么。这不是alias
-这是指针&alias
为您提供指向alias
所在的内存位置的指针,而该指针又指向结构T
所在的内存位置。您的定义最容易引起误解。两个指针可以指向同一位置。我不喜欢“关联相同位置”的措辞。它们字面上存储其他变量的位置。“别名”有一个非常具体的含义,而这不是其中之一。这些独立指针恰好共享相同的值,而不是别名。在其他语言(例如C++)中,有更多类似别名的功能,例如引用,其中两个事物可以被视为相同的,修改一个引用会修改对同一事物的所有其他引用,因为它们是相同的。