dri*_*ker 31 c compound-literals
我正在尝试将复合文字分配给变量,但似乎不起作用,请参阅:
int *p[] = (int *[]) {{1,2,3},{4,5,6}};
Run Code Online (Sandbox Code Playgroud)
我在gcc中遇到错误.
但如果我只写这个:
int p[] = (int []) {1,2,3,4,5,6};
Run Code Online (Sandbox Code Playgroud)
那没关系.
但这不是我想要的.
我不明白为什么错误发生,因为如果我像数组一样初始化它,或者使用字符数组的指针,它没关系,请参阅:
int *p[] = (int *[]) {{1,2,3},{4,5,6}}; //I got a error
int p[][3] = {{1,2,3},{4,5,6}}; //it's okay
char *p[] = (char *[]) {"one", "two"...}; // it's okay!
Run Code Online (Sandbox Code Playgroud)
注意我不明白为什么我在第一个错误中得到错误,请我不能,或者我不想写第二个表单,因为它需要是复合文字,我不想要说数组到编译器有多大.我想要第二个,但是对于int值.
提前致谢.
Jud*_*den 31
首先,在所有示例中,强制转换都是多余的,可以删除.其次,您使用语法初始化多维数组,并且需要定义第二个维度以分配顺序内存块.相反,请尝试以下两种方法之一:
多维数组:
int p[][3] = {{1,2,3},{4,5,6}};
Run Code Online (Sandbox Code Playgroud)指向一维数组的指针数组:
int p1[] = {1,2,3};
int p2[] = {4,5,6};
int *p[] = {p1,p2};
Run Code Online (Sandbox Code Playgroud)后一种方法具有允许不同长度的子阵列的优点.然而,前一种方法确保存储器连续布局.
我强烈建议您不要使用的另一种方法是在字符串文字中编码整数.这是一个非便携式黑客.此外,字符串文字中的数据应该是常量.你的阵列需要是可变的吗?
int *p[] = (int *[]) {
"\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
"\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00"
};
Run Code Online (Sandbox Code Playgroud)
这个例子可能适用于32位小端机器,但是我在iPad上输入此内容并且目前无法验证它.再次,请不要使用它; 甚至提起它我都觉得很脏.
您发现的转换方法似乎也可以使用指向指针的指针.它也可以像多维数组一样被索引.
int **p = (int *[]) { (int[]) {1,2,3}, (int[]) {4,5,6} };
Run Code Online (Sandbox Code Playgroud)
Mah*_*esh 13
首先要明白"数组不是指针".
int p[] = (int []) {1,2,3,4,5,6};
Run Code Online (Sandbox Code Playgroud)
在上面的例子中p是一个整数数组.将元素复制{1,2,3,4,5,6}到p.类型转换在这里没有必要并且两个rvalue和lvalue类型匹配这是一个整数阵列等没有错误.
int *p[] = (int *[]) {{1,2,3},{4,5,6}};
Run Code Online (Sandbox Code Playgroud)
"注意我不明白为什么我在第一个错误中出现错误,......"
在上面的例子中,p是一个整数指针数组.但它{{1,2,3},{4,5,6}}是一个二维数组(即[] []),不能被类型转换为指针数组.你需要初始化为 -
int p[][3] = { {1,2,3},{4,5,6} };
// ^^ First index of array is optional because with each column having 3 elements
// it is obvious that array has two rows which compiler can figure out.
Run Code Online (Sandbox Code Playgroud)
但为什么这个陈述会编译?
char *p[] = {"one", "two"...};
Run Code Online (Sandbox Code Playgroud)
字符串文字与整数文字不同.在这种情况下,p也是一个字符指针数组.实际上说"one",它可以被复制到一个数组或指向它的位置,将其视为只读.
char cpy[] = "one" ;
cpy[0] = 't' ; // Not a problem
char *readOnly = "one" ;
readOnly[0] = 't' ; // Error because of copy of it is not made but pointing
// to a read only location.
Run Code Online (Sandbox Code Playgroud)
使用字符串文字,上述任何一种情况都是可能的.所以,这就是声明编写的原因.但是 -
char *p[] = {"one", "two"...}; // All the string literals are stored in
// read only locations and at each of the array index
// stores the starting index of each string literal.
Run Code Online (Sandbox Code Playgroud)
我不想说数组对编译器有多大.
动态分配内存malloc是解决方案.
希望能帮助到你 !
因为没有人说过:如果你想要一个指向2D数组的指针,你可以(可能)做类似的事情
int (*p)[][3] = &(int[][3]) {{1,2,3},{4,5,6}};
Run Code Online (Sandbox Code Playgroud)
编辑:或者你可以有一个指向其第一个元素的指针
int (*p)[3] = (int[][3]) {{1,2,3},{4,5,6}};
Run Code Online (Sandbox Code Playgroud)
您的示例不起作用的原因是因为{{1,2,3},{4,5,6}}它不是类型的有效初始值设定项int*[](因为{1,2,3}它不是有效的初始值设定项int*).请注意,这是不是一个int[2][3]-它只是一个无效的表达.
为什么它的字符串的原因是因为"one"是一个有效的初始化char[]和char[N](对于一些N> 3).作为一个表达式,它大致相当于(const char[]){'o','n','e','\0'}除了编译器在失去constness时不会抱怨太多.
是的,初始化器和表达式之间存在很大差异.我很确定char s[] = (char[]){3,2,1,0};C99中的编译错误(可能是C++前置0x).还有许多其他的东西,但是T foo = ...;变量初始化,而不是赋值,即使它们看起来相似.(它们在C++中特别不同,因为不调用赋值运算符.)
与指针混淆的原因:
T[]会隐式转换为type T*(指向其第一个元素的指针).T arg1[]在函数参数列表中实际意味着T * arg1.您无法将数组传递给各种原因的函数.这不可能.如果你尝试,你实际上是传递一个指向数组的指针.(但是,您可以将包含固定大小数组的结构传递给函数.)编辑:观察者可能会注意到我的第一个例子大致在语法上等同于int * p = &1;,这是无效的.这适用于C99,因为函数内的复合文字"具有与封闭块相关联的自动存储持续时间"(ISO/IEC 9899:TC3).