2014-02-23 152 views
0

请看下面的代码片段字符数组初始化

char ch[10] = "hello"; // is ok 

char ch[10]; 
ch = "hello"; // showing lvalue error 

它应该有根据该数组衰变为pointer.Why概念有可能在这里通道不衰减到char *? 请描述两者之间的区别。

+0

你知道什么是“左值”吗? –

+0

是的。这些是占用内存空间并且可以指定或不可指定的值。 – YakRangi

+0

是,左值是可赋值的值。在你的情况下,ch指向它自己的第一个元素的地址,即它的基地址。所以你不能改变数组的基地址,而你可以改变数组的基地址的值。因此在这种情况下'ch'不是'lvalue'。请参阅我的答案以供参考 –

回答

1

壳体1: -

char ch[10] = "hello";

取的基地址为1000

通过您的声明

1000 - >ħ
1001 - >电子
1002 - > l
1003 - > l
1004 - >ö
1005 - > \ 0

和CH指向1000

壳体2: -

char ch[10];
ch="hello";

1000 - >垃圾
1001 - >垃圾
1002 - >垃圾
1003 - >垃圾
1004 - >垃圾
1005 - >垃圾

注意hello是具有它自己的地址的独立字符串,因此通过ch="hello"

您试图ch"hello"指向的h新地址。

这是不可能的,因为ch的类型是char *const

我的意思是说ch将始终指向它的基地址,并且不能更改数组的基地址。

您可以更改数组的值,但不能更改数组元素的地址。

0

无法使用赋值运算符(如第二个示例)在C中定义整个数组的内容。第一个例子是该规则的一个例外:在定义点初始化文件是合法的。

“数组衰减为指针”不是描述指针/数组对偶性的正确方法:数组仅在作为参数传递给函数时才转换为指向其第一个元素的指针。只有当元素是数组的第一个元素时,才能使用[]对指向元素的指针进行索引。如果没有,编译器不会抱怨,但结果是未定义的。

与应用于指针不同的是,大多数其他操作符在应用于数组时是非法的。

+2

“无法使用C初始化整个数组,例如您的第二个示例。” - 您将初始化与赋值混淆。你当然可以*初始化一个数组。 –

+1

*“只有当数组作为参数传递给函数时,数组才被转换为指向其第一个元素的指针”* - 不正确。例如; 'char c [size]; char * p = c;'或'char a [10]; char c = *(size + 5);'。 *“只有元素是数组的第一个元素时,才可以使用[]指向元素的索引,否则编译器不会抱怨,但结果是未定义的。 char a [10]; char * p = &a[5]; char c = p [2]'是完全有效的。对不起,这是一个很文雅的人,但是,你知道......这就是我们所做的。 –

+0

:D你是绝对正确的!这对我来说太早了,我没有清楚地想... –

0

ch =“hello”不是初始化,它是分配。还有"hello"类型和ch类型是不同的。

将其更改为char ch[10] ="hello"

2

数组不可分配。如果你需要动态地分配一个字符串,那么你要么A)事先创建一个固定长度的缓冲区并填充它,要么B)动态地分配内存,并且再次填充它。

这一切都取决于你是否事先知道大小(虽然C支持可变长度数组,但要小心),或者如果你需要容纳任意长度的字符串。

为字符串复制到现有的缓冲液(用自动存储持续时间或以其他方式分配),可以使用strcpystrncpy(用于插入到现有的字符串),strdup(POSIX),与fgets,或任何其他方法来读取它在是适当的。请注意缓冲区大小和字符串长度。

1

char ch[10]; 
ch = "hello"; 

不是C.无效宣告你的阵列后,你不能将其重新分配。数组的名称实际上是该数组的第一个元素的地址。 ch是一个数组,hello也是数组,它没有名称但具有它自己的地址,所以此ch = "hello";行是尝试使用另一个地址重新分配ch,这是无效的。 你只

strcpy(ch,"hello"); 

为了能够把hello进去

2
char ch[10] = "hello"; 

是初始化,并通过标准允许的。它实际上“给我一个十个字符的数组,并用C字符串"hello"填充它。

char ch[10]; 
ch = "hello"; 

是(企图)分配,并且是不允许的。你可以这样做:

char *ch; 
ch = "hello"; 

但你结束了,你不允许修改ch(这是不确定的行为是否或不是你不允许修改字符串常量)。

一种方式来获得“转让”初始化时间后与阵列发生的事情是:

char ch[10]; 
strcpy (ch, "hello"); 
2

你应该明白初始化和赋值的区别。初始化定义了一个变量,并在同一个语句中给它赋值。以下语句定义类型为char[10]的变量ch - 10个字符的数组,然后为其指定字符串文字。

char ch[10] = "hello"; 

这相当于

char ch[10] = {'h', 'e', 'l', 'l', 'o', '\0'}; 

请注意,您只分配阵列ch的第一6元素,其余4被隐式初始化为空字符 - '\0'。因此,上述两种说法有一样的:

char ch[10] = {'h', 'e', 'l', 'l', 'o', '\0', '\0', '\0', '\0', '\0'};  

的任务是当你第一次定义一个变量,然后在另一份声明中为它分配一个值。

char ch[10]; // define ch of type char[10]. contains garbage right now. 

只是因为它包含垃圾值定义后,则不应使用ch。接下来,你应该为它赋值,但是不能像初始化时那样赋值。这是C的规则所不允许的。您不能一次性分配数组的所有元素,但必须分别分配数组中的每个元素。

char ch[10]; 
const char *s = "hello"; 
int len = strlen(s); 
for(int i = 0; i <= len; i++) // copy the null byte as well 
    ch[i] = s[i]; 

在这里,你只分配数组ch的第一6元素,其余4仍然含有垃圾值,除非你将它们分配。这是数组初始化和赋值之间的区别。