0
#include <stdio.h>

main()
{
  char * ptr;

  ptr = "hello";


  printf("%p %s" ,"hello",ptr );

  getchar();

}

嗨,我想清楚地了解如何将数组分配给指针。我注意到,当您将一个字符数组分配给一个字符指针时,ptr="hello";该数组会衰减到该指针,但在这种情况下,我正在分配一个不在变量内部且不是包含它们的变量的数组字符“,这样做分配取一个专门用于"Hello"(显然正在发生的事情)的内存地址,并且是否可以修改“Hello”中每个元素的值,这些元素包含在存储该数组的内存地址中。作为比较,是否可以我用一个数组分配一个指针,例如ints像这样模糊的东西int_ptr = 5,3,4,3;并且值 5,3,4,3 与“Hello”一样位于内存地址中。如果不是,为什么只能使用字符串?提前致谢。

4

4 回答 4

3

"hello"是一个字符串文字。它是一个无名且不可修改的类型对象char [6]。它是一个数组,它的行为方式与任何其他数组的行为方式相同。它是无名的事实并没有真正改变任何东西。您可以将其与[]运算符一起使用,例如 in"hello"[3]等。就像任何其他数组一样,它可以并且将在大多数情况下衰减为指针。

您不能修改字符串文字的内容,因为它在定义上是不可修改的。它可以物理存储在只读存储器中。如果它们包含常见的字符子序列,它可以与其他字符串文字重叠。

通过复合文字语法,其他数组类型也存在类似的功能

int *p = (int []) { 1, 2, 3, 4, 5 };

在这种情况下,右侧是一个类型为 的无名对象int [5],它衰减为int *指针。复合文字是可修改的,这意味着您可以这样做p[3] = 8并因此替换48.

您还可以对 char 数组使用复合文字语法并执行

char *p = (char []) { "hello" };

在这种情况下,右侧是一个可修改的无名类型对象char [6]

于 2013-01-05T01:33:16.717 回答
1

您应该做的第一件事是阅读comp.lang.c FAQ的第 6 部分。

字符串字面"hello"量是一个类型的表达式char[6](“hello”为 5 个字符,结尾为 1 个字符'\0')。它指的是一个具有静态存储持续时间的匿名数组对象,在程序启动时初始化为包含这 6 个字符值。

在大多数情况下,数组类型的表达式被隐式转换为指向数组第一个元素的指针;例外情况是:

  • 当它是sizeof(的参数时,sizeof "hello"产生 6,而不是指针的大小);
  • 当它是_Alignof(C11 中的一个新特性)的论点时;
  • 当它是一元的参数时&&arr产生整个数组的地址,而不是其第一个元素的地址;相同的内存位置,不同的类型);和
  • 当它是用于初始化数组对象的初始化程序中的字符串文字时(char s[6] = "hello";复制整个数组,而不仅仅是指针)。

这些例外都不适用于您的代码:

char *ptr;
ptr = "hello";

所以表达式"hello"被转换为(“衰减”到)指向'h'我上面提到的那个匿名数组对象的第一个元素()的指针。

因此*ptr == 'h',您可以ptr通过记忆前进以访问其他字符:'e''l''l''o''\0'printf()当你给它一个"%s"格式时,这就是它的作用。

与字符串文字相关联的匿名数组对象是只读的,但不是const. 这意味着任何修改该数组或其任何元素的尝试都具有未定义的行为(因为标准明确说明了这一点)——但编译器不一定会警告您。(C++ 生成字符串文字const;在 C 中做同样的事情会破坏在添加到语言中之前编写的现有代码const。)所以不,你不能修改"hello"- 或者至少你不应该尝试的元素。为了让编译器在您尝试时发出警告,您应该将指针声明为const

const char *ptr; /* pointer to const char, not const pointer to char */
ptr = "hello";

(gcc 有一个选项 ,-Wwrite-strings导致它将字符串文字视为const。这将导致它警告一些就标准而言是合法的 C 代码,但此类代码可能应该修改为使用const。)

于 2013-01-05T05:55:13.810 回答
0
#include <stdio.h>

main()
{
   char * ptr;

   ptr = "hello"; 

  //instead of above tow lines you can write char *ptr = "hello" 

   printf("%p %s" ,"hello",ptr );

   getchar();

}

在这里,您已为其分配了字符串文字"hello"ptr这意味着字符串文字存储在只读内存中,因此您无法修改它。如果您声明char ptr[] = "hello";,那么您可以修改数组。

于 2013-01-05T05:32:46.850 回答
-2

说什么?

您的代码分配了 6 个字节的内存并使用值 'h'、'e'、'l'、'l'、'o' 和 '\0' 对其进行初始化。

然后它分配一个指针(指针的字节数取决于实现)并将指针的值设置为前面提到的 5 个字节的开头。

您可以使用诸如ptr[1] = 'a'.

从语法上讲,字符串是一种特殊情况。由于 C 没有特定的字符串类型可言,它确实提供了一些快捷方式来声明它们等。但是您可以轻松地创建与使用字符串创建相同类型的结构int,即使语法必须有点不同。

于 2013-01-05T01:31:23.517 回答