当我们可以做char * string =“string”时,如何指针“值为地址的变量”?

时间:2014-02-27 19:19:44

标签: c string pointers

我总是理解指针如下:

int x = 5;
int *y = &x;

printf("%d", *y);
  • 我将5存储在某个内存位置,并允许自己使用x访问该值。
  • 我创建了一个整数指针y,将其内存位置设置为x的内存位置。
  • 我打印存储在y持有的地址的值。

然而,我可以同时做char *string = "neato"并且它完全有效。对我来说,这看起来像“创建一个字符指针,保持内存地址'neato'”。这有什么用呢?

此外,如果我设置它,我会尝试将其作为*string = "more neat",但这会产生错误。我需要做string = "more neat"。第一次尝试直观地看起来像“将存储在由字符串保存的内存地址的值更改为'更整洁'”,但它不起作用。第二个看起来像“对于'字符串'所持有的内存地址,将其更改为'更多neato'。这对我来说完全没有意义。

我有什么困惑?如果为了访问存储在指针中的值我需要printf("%d", *pointer),那么如何设置的值不是沿着这些行?

4 个答案:

答案 0 :(得分:2)

一元*运算符有两个不同(但相关)的目的。在声明中,它表示该类型是指针类型,但并不意味着指针被解除引用。

表达式中使用时,表示引用指针。这就是为什么你的例子在它声明的地方工作的原因,但当你取消引用它时你不能分配(因为如果你可以修改字符串文字,那么分配的适当类型将是一个字符。)

在声明之外执行此操作的等效方式如下:

const char *s = "hello"; /* initialize pointer value */
s = "goodbye"; /* assign to pointer value */

上述初始化和赋值是等效的。

答案 1 :(得分:1)

"neato"属于const char[]类型。在适当的时候,数组会衰减到指针,因此赋值是指向另一个的指针。

然后你的指针应该是const char。写入由字符串文字占用的内存位置会调用未定义的行为。但这是有效的:

char str[] = "neato";
str[0] = 'p';
  

此外,如果我设置它,我会尝试将其作为* string =“more neat”

好吧,你有一个指向 char 的指针,所以这个赋值没有意义(也就是我上面写的关于写一个字符串文字的内容。)

答案 2 :(得分:1)

char *和字符串“neato”的基本类型是char;字符串文字只是字符数组,通常位于只读地址中。 “n”必须位于地址中(因为必须是下一个字符“e”,依此类推)。该地址存储在变量char *ptr;

问题的第二部分是为什么*ptr = "more neat";无效。

*var取消引用地址 - 在这种情况下是1个字符的宽内存地址,其中包含字符'n'。您不能将新字符串文字的地址(可能以4或8字节表示)放入单个字符;你也不能把9个字符和终止的ascii-zero放在里面。

我们可以通过对16位(Big Endian)机器进行内存转储来研究这个问题;

  0FFE: .. ..             // other variables, return addresses etc.
  1000: F0 00             // The pointer "var" is located here
  1002:                   // Top of stack

  F000: "n" "e" "a" "t" "o" 00      // Address of constant string is F000
  F006: "m" "o" "r" "e" ...         // Address of next string is F006

*var访问F000的单字节内存。 var本身位于地址0000,并且在此机器中有两个字节,因为地址在这里是16位宽。新作业var="more neat"之后;内存转储是:

  1000: F0 06             // Pointer holds a new address

答案 3 :(得分:0)

例如,

char *ptr = "neato";
char arr[] = "neato"; 

完全不同。 ptr 是指向字符串文字“neato”的指针,编译器通常将字符串文字存储在只读内存中。因此,您无法将字符串文字 ptr 更改为,但您可以更改 ptr 的值,即地址。

*ptr = "more neat"; // error, even if *ptr were writable, it should be a character
*ptr = 'b'; // error
ptr = "more neat"; // ok, you just create another string literal and ptr now points to it

第二个只是

的缩写
char arr[] = {'n', 'e', 'a', 't', 'o', '\0'};

在这种情况下,您可以更改数组中的字符,但不能更改arr的地址(是的,它是一个数组)

*arr = 'b'; // ok
arr = "more neat" // error, the value of arr, namely the address of the array cannot be changed

初始化和分配是不同的,即使它们看起来非常相似,但操作的含义通常是不同的。