不需要额外变量,初始化指向数组字面量的指针

10

我有一个变量需要保存指向数组的指针。 通常情况下,可以先创建一个包含数组的变量,然后保存该变量的指针。但是,我需要对大约10个变量执行此操作,而我不想为它们中的每一个额外创建一个数组。 我最初尝试的方法是

int *numList = {1, 2, 3};

但是它试图创建一个指向整数的指针数组。我认为下面的代码具有正确的列表类型,但我不知道如何将数组强制转换为指针。

int (*numList)[3] = {1, 2, 3};

很难想象为什么需要10个指针来...没有什么重要的东西。主要问题是什么? - Jacek Cz
是的,这正是我一直在想的——你想要实现什么目标? - deLock
基本上,我正在使用另一种(更高级别的)语言编写GUI,它将生成一堆指令,包括这些数组中的数据,形式为C代码。然后,C代码将被编译并上传到特定的硬件设备上,该设备将执行这些指令。 - Matthias
4个回答

12

在C99和C11中,您可以使用复合字面值来实现问题标题中所要求的内容,即初始化指针,使其指向一个数组字面量而不需要任何额外的变量:

int *numList = (int []){ 1, 2, 3 };
< p > numList 指向的数组与指针本身具有相同的作用域和生命周期 - 如果它在函数内部,则持续到定义它的块结束,如果它在任何函数之外,则持续到程序的运行时间。

如果你在函数内部创建 static int *numList = (int []){ 1, 2, 3};,那么你会为自己带来麻烦 - 不要这样做。(在文件范围内,在任何函数之外,它不会出现任何问题。)指针将在第一次调用函数时初始化,但不能保证它所指向的具有静态持续时间,并且随后的调用可能指向垃圾。


谢谢,这正是我想要做的。 - Matthias

1
标准规定:
除了作为sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串字面量之外,具有“类型为数组”的表达式会被转换为“类型为指向该类型的指针”的表达式,该指针指向数组对象的初始元素,且不是lvalue。
你可以将数组分配给int[]类型,因为从实际上讲,数组本身就像是自动衰减为指针,所以不需要“将数组强制转换为指针”。
简而言之,从实际角度来看,int[] 被视为一个int*。数组实际上是指向其第一个元素的指针:
int array[] = { 1, 2, 3 };

现在,您可以将此对象传递给具有原型void func(int *array);的函数,而无需将其转换为int *。也就是说,您可以将其称为func(array)
一些相关事实是array == &array。因此,您永远不需要显式地将数组转换为指针,因为那是多余的。
有关更多信息,请查看什么是数组衰减?

你的引用似乎来自C99; [C11 §6.3.2.1 Lvalues,arrays和function designators](http://port70.net/~nsz/c/c11/n1570.html#6.3.2.1p3)列出了_Alignof和字符串字面量用于初始化数组作为其他例外情况。 6.3的一般主题是“转换”。 我不同意你的观点:“int [] is an int *”-这是错误的。 数组可以轻松转换为指针,但这并不等同于说数组*与指针相同。 您还没有回答主要问题-如何初始化pArray而不定义array - Jonathan Leffler
感谢澄清。就我所知,实际上你不需要显式地将int []转换为int *,因为转换是隐式进行的。这与不需要将任何指针转换为void *的原因类似。对于他们的问题,我的回答是他们不应该将整数数组强制转换为整型指针,而是将对象分配给int [],因为对象本身就是这样的。当他们将这个对象传递到其他地方时,不需要进行转换。 - neuro_sys

-1

数组名本身就是指向数组第一个元素的指针。

也就是说,在你的例子中,

int numList[3]={1,2,3};

numList指向1。
如果您想将此数组的指针传递给函数,例如
void sort(int *array)
{
//do something
}

你可以将你的数组名称作为参数调用这个函数。

sort(numList);

“不需要将数组转换为指针”这种说法是不正确的。您不能像使用指针一样使用数组变量的名称。例如,您不能执行*array_name = 1; - deLock
1
你可以使用 *array_name = 1;。数组 不是 指向它们的第一个元素的指针,但在许多情况下,包括 *array_name = 1; 中,它们会自动转换为指向它们的第一个元素的指针。尽管如此,这个答案错误地陈述了“数组名本身是指向数组第一个元素的指针”。 - Eric Postpischil
自动转换为指针并不总是被允许的。而且你也不能像array_name++这样做。所以,不,array_name不是一个指针,你不能像处理指针一样处理它。因此,我的反对是有效的——将数组转换为指针是没有必要的,这是不正确的说法。 - deLock

-1
int (*numList)[3];

FYG,这是一个指向包含3个整数的数组的指针(方括号比*具有更高的优先级);你不能用这种方式初始化它。


1
numList 可以在此声明中使用 int (*numList)[3] = (int [][3]) {{3, 4, 5}}; 进行初始化。 - Eric Postpischil
虽然该内容在初始化的注释之前是准确的,但它并没有回答这个问题。 - Jonathan Leffler

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