二维数组和指针 - C

3

我正在努力理解C语言中的数组和指针以及它们之间的区别,但在处理二维数组时遇到了些麻烦。

关于普通的一维数组,我已经学习了以下内容:

char arr[] = "String constant";

创建一个字符数组,变量arr将始终表示初始化时创建的内存。
char *arr = "String constant";

创建了一个指向字符数组"字符串常量"的第一个索引的char指针。该指针以后可能会指向其他位置。

char *point_arr[] = {
    "one", "two","three", "four"
};

创建一个指向字符数组"one"、"two"等的指针数组。

我的问题

如果我们可以同时使用:

char *arr = "constant";

并且

char arr[] = "constant";

那么,为什么我不能使用以下内容:
char **pointer_arr = {
    "one", "two", "three", "four"
};

替代

char *pointer_arr[] = {
    "one", "two", "three", "four"
};

如果我尝试使用char **,那么我会得到一个错误,如“标量初始化程序中存在过多的元素”。我可以通过使用calloc来专门分配内存来使char**示例工作,但是因为我不必像使用char *arr = "blah";时那样做。我不明白为什么这是必需的,所以我真的不理解以下两者之间的区别:

char **arr_pointer;

并且

char *arr_pointer[];

非常感谢您提前给予的建议。


我相当确定这是一个重复的内容... - Mitch Wheat
略微相关的是,第二、第三和第四个例子应该是“const”。 - Matteo Italia
1
@Matteo:在C语言中,使用const来表示字符串字面量是很好的风格,但并不是必须的。 - schot
@schot:这不是必需的,但我记得字符串字面值的const char *char *的隐式转换只是为了兼容性而存在,并且可能(我不确定)已经在C99中被弃用。 - Matteo Italia
5个回答

5

请参见C语言FAQ中的这个答案

其中解释了char []char *之间的区别。同样的道理可以扩展到char *[]char **之间。


3
简而言之,您不能将{ ... }用作标量的初始化程序。 char **arr_pointer声明了一个标量,而不是一个数组。相反,您可以使用char *arr = "constant";是因为您仍然声明了一个标量,只是它指向一个字符串文字。

1
严格来说,你可以使用{...}作为标量的初始化器。在C语言中,int x = {5}是完全合法的。编译器抱怨的是过多的初始化器。虽然OP的问题不是关于这个的... - AnT stands with Russia

1

如果你真的想深入了解它,那么尝试通过int而不是char来理解数组和指针。根据我的经验,在涉及char时,我很难理解指针和数组。一旦你正确理解了int,你就会意识到这并不难。

int *ptr[]是一个指向整数的指针数组,而int **ptr是一个指向指针的指针,引用一个整数。

int *arrptrs[2];
arrptrs[0]=(int *)malloc(sizeof(int)*5);
arrptrs[1]=(int *)malloc(sizeof(int)5);
这将初始化由数组arrptrs的元素引用的两个数组。数组的名称指的是数组的第一个元素的内存位置,因此arrptrs的类型为(int *
),因为该数组的第一个元素的类型为(int *)

假设我们执行 int **ptr=arrptrs 然后, *ptr是arrptrs的第一个元素,即arrptrs[0],而*(ptr+1)是arrptrs[1],执行*arrptrs[0]是由arrptrs[0]引用的数组中的第一个元素。

我希望这可以帮助你,虽然我不确定你是否需要这些信息。


0
指针(char *pointer;)具有值;数组(char array[];)具有元素。
声明char **ptr2 声明了一个只能接受单个值的对象,而不是可以接受多个元素的对象。

0

维基百科的引用:

在计算机中,标量变量或字段是一种只能一次保存一个值的变量... ...例如,在C编程语言中,char、int、float和double是最常见的标量数据类型。

正如Oli Charlesworth在他的回复中指出的那样,使用{...}初始化多个项,但是由于char **arr_pointer是一个“标量”,因此一次只能指向1个东西(一个地址),所以这里不能使用{...}符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接