繁体   English   中英

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

[英]How are pointers “variables whose values are an address” when we can do char *string = “string”?

我一直对指针的理解如下:

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

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

但是,我可以同时执行char *string = "neato" ,它完全可以正常工作。 对我来说,这就像“创建一个字符指针,保存内存地址'neato'”。 这有什么意义?

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

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

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

当在表达式中使用时,它表示递减指针。 这就是为什么您的示例在声明的地方起作用的原因,但是在取消引用它时,您就不能分配(因为要分配的适当类型将是char,如果您可以以任何方式修改字符串文字)。

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

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

上面的初始化和分配是等效的。

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

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

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

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

好吧,您有一个指向char的指针,因此分配没有任何意义(也是我上面所说的关于写字符串文字的内容。)

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

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

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

我们可以通过对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

例如,

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

初始化和赋值是不同的,即使它们看起来很相似,操作的含义也常常是不同的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM