C 这个代码是做什么的?内存分配

C 这个代码是做什么的?内存分配,c,memory,memory-management,C,Memory,Memory Management,有人能帮我更好地了解内存分配的工作原理吗?如果有人能一步一步地(希望有图片)看一下这段代码中发生了什么,我将不胜感激: char a[3][4] = {"xy", "abcd", "!?"}; char (*b)[4], *c; b = a + 1; c = *a + 1; 我四处看了看,但没有发现任何东西能彻底解释这一点,谢谢 编辑: 如果有人能用memoryblock解释一下,我将不胜感激,例如,[x][y][[a][b][c][d][] #include <stdio.h>

有人能帮我更好地了解内存分配的工作原理吗?如果有人能一步一步地(希望有图片)看一下这段代码中发生了什么,我将不胜感激:

char a[3][4] = {"xy", "abcd", "!?"};
char (*b)[4], *c;
b = a + 1;
c = *a + 1;
我四处看了看,但没有发现任何东西能彻底解释这一点,谢谢

编辑: 如果有人能用memoryblock解释一下,我将不胜感激,例如,[x][y][[a][b][c][d][]

#include <stdio.h>

int main(int argc, char *argv[])
{
  // the second dimension should 5
  // since "abcd" is 4 chars + null terminator
  char a[3][5] = {"xy", "abcd", "!?"};
  char (*b)[5], *c;
  b = a + 1;
  c = *a + 1;

  // b = a + 1, thus it points to the second entry of a array
  printf("%s\n", b[0]);

  // c = *a + 1, thus it points where a points to, plus one,
  // thus in the second letter of a's first entry
  printf("%c\n", *c);
  return 0;
}
用零表示空终止符。请注意,在您的示例中,拥有一个字符串并不重要,但我认为在C中拥有以null结尾的字符串总是一件好事。这就是为什么我稍微更改了您的代码


为什么
a
中的每个字符串不只有一个空终止符?参见答案。

变量
a
char
的数组。变量
b
是指向
char
数组的指针,
c
是指向“char”的指针


变量
a
在声明时初始化。然后将变量
b
分配给指向
a
的第二个数组(即
a[1]
),并将
c
分配给
a[0]
的第二个字母

至于
b
的赋值,表达式
a[1]
*(a+1)
是等价的

对于
c
的赋值,
a
本身是指向数组第一个元素的指针,即它是
a[0]
a
&a[0]
相同)。通过取消对
a
的引用,您将获得
a
的第一个条目,即您将获得
a[0]
。将一个字符添加到
a[0]
会给您提供
a[0]
的第二个字符,即
a[0][1]

char a[3][4] = {"xy", "abcd", "!?"};
第一个命令在堆栈上分配一个3×4矩阵,并用一些字符初始化二维数组的元素

char (*b)[4], *c;
保留指向堆栈上名为b的大小为4的字符数组的指针。此外,它还创建了第二个名为c的字符指针

b = a + 1;
将数组a+1的起始地址存储在指针b中,表示第二个元素的地址(第二行,共4个字符)


您取消引用a,生成指向a的第一个元素的指针(a的元素是大小为4的字符数组),并向该指针添加1,这是第一个条目的第二个字母。

它可以被视为不起任何作用,因为它没有副作用……是否应使用超大字符串“abcd”,长度为5个字符,包括终止符,填充到一个较小的四字符数组中,在提供的任何答案中都可以解释吗?@WhozCraig-Nope,这不是问题<代码>字符foo[3]=“foo”定义良好,如果文本正好是数组的长度,则不添加终止符。@是否展开C?C++会对此提出异议。Egads。@非常感谢您提供的信息。讨厌。这并不是一个终结者搜索超越了等待的范围。在堆栈4个元素和4个元素上保留一个名为b的字符指针:这意味着什么?
b
实际上是一个“指向4个字符数组的指针”。我不是100%肯定的,但我认为sizeof(*b)应该是4,而不是1。空终止符不应该是1,后面才是。例:[x][y][\0][[a]..号@Fjondor,因为您使用的是初始值设定项列表,所以所有空单元格都将被零初始化。@Fjondor我包含了一个链接,这可能会有所帮助。括号解释有用吗?
b = a + 1;
c = *a + 1;