将字符数组分配给另一个字符数组

7

我知道我们不能将一个字符数组直接赋值给另一个字符数组,例如:

 char array1[] = "Hello";
 char array2[] = "Hi!";

 array1 = array2;//does not compile

但是:

 char array1[] = "Hello";
 char *array2 = NULL;

 array2 = array1; //compile

 printf("%s", array2); //display Hello

这个有效。

请问有人能解释一下为什么吗?

谢谢!

4个回答

7

普通数组是不可赋值的。这就是为什么第一个代码示例不起作用的原因。

在第二个示例中,array2 只是一个指针,而 array1,尽管是一个数组,在某些情况下可以 退化 为指向其第一个元素的指针。这就是这里发生的情况:

array2 = array1;

完成此赋值操作后,指针array2将指向数组array1的第一个元素。此处没有进行数组赋值操作,而是进行了指针赋值操作。


1
为了完整起见,您可能需要提到const和strcpy。 - technosaurus
1
旁注:我总觉得如果数组像一等对象一样对待,C++ 就会是一种更整洁的语言。也就是说,如果为数组定义了 []= 等运算符(而不是需要进行数组到指针转换),那将会很好且统一。 - Joseph Mansfield
谢谢!现在我明白了。 - user3885884

1

就像这样:

对于编译器来说,两者都被视为指针,但区别在于:

  • char array1[] = {...} 是一个固定的指针,它指向内存中的一个固定区域(在这种情况下,它在堆栈中)

  • char *array2 = ... 是一个可变指针,可以指向任何内存点(当然需要权限)

在第一种情况下,编译器甚至知道数组的大小,而在第二种情况下,编译器只知道它是一个指针,因此它无法知道它所指向的数组的大小。

因此,对于printf(),两者都是指针...


3
我认为它们并不都被视为指针。只有当你开始访问数组的元素时,你才开始涉及到指针。 - Joseph Mansfield
是的,有点像……但它们之间有什么区别呢?第一种情况下编译器拥有更多信息……我没有看到其他区别……我没有实际的正式答案。这只是一个观点…… - Wagner Patriota
2
当你想在这个StackExchange(特别是C语言)的指针讨论中做出贡献时,请先考虑一下“迂腐的”、“精确的”、“特定的”、“挑剔的”、“痛苦的”、“回报”的词语(还有很多其他的)。然后再决定是否要加入讨论。当你发表一个不是基于一组迂腐规则的特定声明时,会有人来挑毛病。这有时会很痛苦,但如果你愿意学习,长期来看应该会有回报。 - ryyker
好的...你是对的...但为什么数组不能被视为指针呢?除了赋值和sizeof()操作之外,我就是想不起来有什么情况与指针不同了... - Wagner Patriota
@WagnerPatriota:我认为你在评论中已经回答了自己的问题。 - rici
这个问题本身不就是表明数组和指针的不同吗?数组不能被赋值和复制,而指针可以。 - juanchopanza

1

char array1[]基本上是指向字符数组第一个字母的指针。您可以将此地址分配给另一个指针变量。

以下是一个示例:


#include <stdio.h>

int main(){

    char a[] = "hello";

    char *b;

    a = b;

    printf("%s\n", a);

    return 0;
}


这段代码将输出:
>>> hello 

0

为了更清晰,首先考虑以下代码

char *p = ( char * ) malloc( 6 * sizeof( char ) );

实际上,您动态分配了一个未命名的字符数组,其大小为6个元素,并将该数组的第一个元素的地址分配给指针p。现在,您可以使用此指针来访问数组的任何元素。例如:
p[0] = 'H';
p[1] - 'e';
p[3] = 'l';
p[4] = 'l';
p[5] = 'o';
p[6] = '\0';

printf( "%s\n", p );

同样的方式适用于您的代码片段,只是您使用现有数组的名称,而不是未命名的数组和函数 malloc 返回的地址,该名称以同样的方式调整为指向数组第一个元素的指针。
char array1[] = "Hello";
char *array2;

array2 = array1; 

printf( "%s\n", array2 ); 

因此,数组本身并没有被复制。您只是引入了指向其第一个元素的指针。使用此指针,您可以访问数组的任何元素,因为它指向数组占用的内存区域。

如果您想创建数组的副本,则应编写

#include <string.h>

//...

char array1[] = "Hello";
char array2[sizeof( array1 )];

strcpy( array2, array1 ); 

sizeof(char)1 - Carl Norum
@Carl Norum 你想说什么? - Vlad from Moscow

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