我是C的新手,但对编译器以及堆栈帧的工作原理有相当好的理解。我试图理解如何在堆栈上分配C数组,同时也是指针。例如,取代码:
int a = 101;
int b[5] = {1, 2, 3, 4, 5};
我被告知b是指针。例如'*(b + 1)= 3;'与'b [2] = 3'相同。这是否意味着这里的堆栈帧有a的整数,b的指针和b指向的数组(5 * sizeof(int)bytes)(我称之为这种情况A)或只是一个整数对于a和b的数组(我把这种情况称为B)。
如果情况A为真,为什么C设计者选择以不同的方式实现数组?这是不是意味着数组需要不断地为指针获取额外的内存查找来获取它的地址?
答案 0 :(得分:4)
C没有堆栈的概念。使用正确的术语,我们可以说
int b[5] = {1, 2, 3, 4, 5};
自动存储时间。
恰好,数组索引与取消引用指针完全等效,指针算术在数组中有效。
因此b[2]
和*(b + 2)
是等效的。为了清晰起见,C的设计师这样做了。
“堆栈”上发生的是实现选择,而不是语言选择。
a
和b
之间的关系并不是特别相关。请注意,您无法通过a
的一些好奇索引“到达”b
(反之亦然)。尝试这样做的行为是 undefined 。
答案 1 :(得分:2)
这是否意味着此处的堆栈帧具有a的整数,b的指针和b指向的数组(5 * sizeof(int)bytes)
int b[5] = {1, 2, 3, 4, 5};
你的b
是一个数组,而不是一个指针。所以b
是一个包含五个连续整数的内存块。
如果您声明了一个额外的指针
int *c = b;
那么这就像你在情境B中所描述的那样,即你有一个指向数组开头的指针。