C
让我足够频繁地交替使用char
指针和数组,以至于我经常认为它们是完全可互换的。但是下面的代码证明了这是不正确的。谁能解释下面的代码为什么用三元运算符初始化const char d[]
是非法的?
/* main.c */
#include <stdio.h>
int main()
{
const char* a = "lorem";
const char b[] = "ipsum";
int* p;
const char* c = ( *p ? "dolor" : "sit" );
const char d[] = ( *p ? "amet" : "consectetur" ); // Why am I an error?
return 0;
}
编译:
> gcc -g main.c
main.c: In function \u2018main\u2019:
main.c:10:20: error: invalid initializer
const char d[] = ( *p ? "amet" : "consectetur" ); // Why am I an error?
相关问题:如果我的术语在这里不准确:描述const char d[]
的正确术语是什么?是数组吗?可变长度数组?还有吗它不被视为指针-是吗?
修改:我相信Array initialization with a ternary operator?
不会回答这个问题 RE:提到的问题,我相信前提略有不同。例如。接受的答案说明{ 1, 2 };
(或{ 'a', 'b' );
)不是有效的C
表达式,我已经知道并接受。但是"amet";
和"consectetur";
是有效的C
表达式。
答案 0 :(得分:5)
6.7.9初始化
...
14字符类型的数组可以由字符串文字或UTF-8字符串初始化 文字,可以选择用大括号括起来。字符串文字的连续字节(包括 如果有空间或数组大小未知,则终止为空字符),初始化 数组的元素。
( *p ? "amet" : "consectetur" )
不是字符串文字,也不是将字符串评估为字符串。它求值为类型char *
的表达式,该表达式本身不是有效的数组初始化器,并且直到运行时才执行该求值。
更不用说,p
尚未初始化,因此表达式的开头没有定义。
答案 1 :(得分:2)
字符串文字有点神奇。通常(在表达式中使用时)它们表示数组。数组可以“衰减”(隐式转换)到指针,这就是为什么。
const char *p = "foo";
有效。 "foo"
是此处的正常表达。你也可以写
const char *p;
p = "foo"; // assignment, not initialization
但是,如果使用字符串文字来初始化数组,则其行为类似于字符的初始化列表:
char s[] = "foo";
// equivalent to:
char s[] = { 'f', 'o', 'o', '\0' };
在您的示例中
const char d[] = ( *p ? "amet" : "consectetur" );
初始化器不是唯一的字符串文字;这是一种表达。因此,两个字符串文字都会衰减到指针,然后您会收到一个错误,因为您无法从指针初始化数组。 (实际上,您根本无法通过表达式初始化数组。)
答案 2 :(得分:0)
您只能使用初始化列表而不是表达式来初始化数组。在您的代码中
const char* c = ( *p ? "dolor" : "sit" );
这里c是指针变量,字符串常量仅表示地址。这就是为什么我们可以使用三元运算符,并且可以将字符串常量的地址分配给指针c并初始化数组的原因。但是
const char d[] = ( *p ? "amet" : "consectetur" );
这里d是一个数组,但d表示数组的地址,字符串常量也仅表示地址。因此,我们无法将地址分配给地址意味字符串常量给数组d。这就是为什么我们会出错的原因。
请访问该链接以获得更好的理解:
https://www.geeksforgeeks.org/whats-difference-between-char-s-and-char-s-in-c/
答案 3 :(得分:0)
在尝试定义d之前,您有错。在尝试定义c时,您会问* p?但是p尚未初始化。我认为行为没有定义。