将字符串赋值给C中的字符指针的说明

时间:2014-07-14 18:38:02

标签: c string pointers

我对指针非常困惑。如果我们创建一个类型为' char'的指针变量,那就像char *ch;那样,并为其分配一个字符数组。然后我们可以通过增加指针(++ ch)来访问字符串中的每个字母。

char *ch;
char a[5]="hello";
*ch=a;
while(*ch) {
  printf("%c",*ch);
  ++ch;
}

这完全没问题。但我看到很多例子,

struct example {
  char *ch;
};

int main() {
  struct example ex={"hello"};
  printf("%s",ex.ch);
}

我对这个例子非常困惑,比如如何直接将字符串分配给字符指针(而不是将字符串赋值给变量,然后将其分配给字符指针)可以使其可访问。在前一种情况下,* ch指向数组的起始内存" a"。但在第二种情况下,指针ch指向哪个内存?谁能给我一个明确的解释呢?

3 个答案:

答案 0 :(得分:2)

进行此作业时

ch=a;

您正在将指针ch设置为字符数组a[]的开头(注意:数组保持空终止的事实纯属巧合 - 您的代码具有未定义的行为,因为'\0'末尾的第六个字符"hello"不会复制到五个字符的数组中。赋值ch成为存储在数组a[]中的C字符串的“别名”,这意味着您可以将它与字符串操作和格式化例程一起使用。

你的第二个例子不是作业,而是初始化:

struct example ex={"hello"};

用花括号括起来是一个初始化器。 C编译器将采用每个元素(您只有一个,但可能有很多)并将其分配给struct的相应字段。在这种情况下,字符串文字"hello"被分配给ch成员。

初始值设定项的规则是按声明顺序分配花括号中的值。如果您希望使用C99的指定初始化程序功能,您有机会覆盖它:

struct example ex={ .ch = "hello"};

答案 1 :(得分:1)

此代码段

char *ch;
char a[5]="hello";
*ch=a;
while(*ch)
{
printf("%c",*ch);
++ch;

}

有未定义的行为。它可以正常工作你必须将字符数组声明为

char a[6]="hello";

或     char a [] ="你好&#34 ;;

在这种情况下,数组确实会有终止零。

至于此代码段

struct example
{
char *ch;
};
int main()
{
struct example ex={"hello"};
printf("%s",ex.ch);
}

然后在本声明中

struct example ex={"hello"};

编译器首先放置字符串文字" hello"在内存中作为具有类型char[6]的字符数组,然后将指向数组的第一个元素的指针分配给结构的数据成员ch。

这两个声明之间的区别

char ch[] = "hello";

char *ch = "hello";

是在第一种情况下创建一个字符数组,其每个元素由字符串文字的相应字符初始化,该字符串文字本身不会存储在内存中。 在第二种情况下,字符串文字将存储在内存中,而指针ch将包含其第一个字符的地址。

答案 2 :(得分:0)

char a[] = "hi";
char *ch = "hello";

此处a是一个大小为3字节的char数组,用于存储,' h',' i'和' \0'。这个内存的3个字节在堆栈中分配以保留字符串。

这里ch是一个指针变量,它存储一个char的地址,ch的大小是4个字节来存储地址(指针的大小是编译器特定的)。然后" hello"是一个常量字符串文字,它将作为只读数据存在于进程内存的文本段中。并且第一个字节的地址被分配给ch变量。为ch变量分配了4个字节的内存来存储堆栈中的地址,文本段中需要5个字节的内存来保持字符串文字" hello"。

有关其他观点的解释,请阅读here