指针初始化为什么?
有一件事总让我困惑,角色指针。 经过四年多的努力,我再次陷入困境。
以上面提到的情况为例。为什么char
指针以这种方式运行? 当指针指向什么都没有时,我们怎么能直接解决指针的内容呢?或者它就像char指针存储除地址之外的东西!
#include #include int main() { char* charPtr="I cant understand why"; int* intPtr=60; printf("%d\n", intPtr); //displays 60 printf("%p\n", intPtr); // displays the hex value of 60 printf("%s\n", charPtr); // displays the wh0le string printf("%p\n", charPtr); // displays the start address of the string return 0;
}
接下来是int
指针,它如何接受值60以及它存储在何处?
抛开char指针和malloc,我认为指针的基本思想是得到一个指向的地址!
为什么这些案件
*intptr = 60 ; // should be setting the pointee's value to 60 intptr = 60 ; // sets the address
抛出编译错误
int* intPtr=60;
偷偷摸摸没有得到一个地址(或者60被视为地址,如果是这样,为什么这在前一种情况下不可接受)的指针!
我想我在这里错过了什么,但是嘿! 你猜怎么着 ? 他们叫我去搜索!
编辑:将char指针指向的地址赋予int指针也会引发错误!
int8_t* intPtr= (int8_t*)0x80485c8 ; // works without casting too ! I guess addresses are acceptable.
取消引用它将给出一个等于字符串的第一个I
的值。这是一个很好的做法,或者存在任何其他解释,省略它们的字节位大小分配,例如int可以保存一个字符串等等?
正如hmjd指出’初始化语法’是问题所在! 我编写自己的代码没有问题,但修改某人的代码时会出现问题!
在C中, 字符串文字如“我无法理解为什么”存储为char
数组,以便在程序的生命周期内可以使用内存(所有地址都是凭空而来的,并不代表任何地址特定平台或架构):
Item Address 0x00 0x01 0x02 0x03 ----- ------- ---- ---- ---- ---- "I..." 0x00080000 'I' ' ' 'c' 'a' 0x00008004 'n' ''' 't' ' ' 0x00008008 'u' 'n' 'd' 'e' 0x0000800C 'r' 's' 't' 'a' 0x00008010 'n' 'd' ' ' 'w' 0x00008014 'h' 'y' 0x00 0x??
字符串文字也是一个数组表达式 ,在大多数情况下,类型为“N元素数组T
”的表达式将转换为“指向T
指针”,其值将是数组的第一个元素的地址(例外情况是数组表达式是sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化数组的字符串文字)。
所以当你写作
char* charPtr = "I can't understand why";
你正在将字符串文字的地址复制到charPtr
:
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- charPtr 0xffbe4000 0x00 0x08 0x00 0x00
请注意,如果声明已经存在
char str[] = "I can't understand why";
str
将被分配为一个足够长的char
数组来保存字符串,并且字符串的内容将被复制到它:
Item Address 0x00 0x01 0x02 0x03 ----- ------- ---- ---- ---- ---- str 0xffbe4000 'I' ' ' 'c' 'a' 0xffbe4004 'n' ''' 't' ' ' 0xffbe4008 'u' 'n' 'd' 'e' 0xffbe400C 'r' 's' 't' 'a' 0xffbe4010 'n' 'd' ' ' 'w' 0xffbe4014 'h' 'y' 0x00 0x??
当你写作
int* intPtr = 60;
您正在使用60初始化指针值,而不是将其设置为指向值为60的匿名整数:
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- intPtr 0xffbe4004 0x00 0x00 0x00 0x3C
地址60很可能不是有效地址,因此尝试取消引用intPtr
很可能会导致未定义的行为。
你写过类似的东西吗?
int x = 60; int *intPtr = &x;
那么你会遇到这样的情况:
Item Address 0x00 0x01 0x02 0x03 ---- ------- ---- ---- ---- ---- x 0xffbe4004 0x00 0x00 0x00 0x3C intPtr 0xffbe4008 0xff 0xbe 0x40 0x04
在这种情况下, intPtr
的值是x
的地址。
最后,请注意初始化和赋值不是一回事。
T *x = value;
不取消引用x
并为结果赋值; 它直接为x
value
。 value
的类型被视为T *
。 请注意,您应该收到警告
int *intPtr = 60;
沿着“从没有强制转换的整数制作指针”这一行。
当指针指向什么都没有时,我们怎么能直接解决指针的内容呢?或者它就像char指针存储除地址之外的东西!
我认为混淆是初始化语法。 这个:
char* charPtr="I cant understand why";
不会取消引用charPtr
。 它相当于:
char* charPtr; charPtr = "I cant understand why";
两个代码片段都将字符串文字"I cant understand why"
的地址存储到charPtr
。 没有解除引用指向任何事物的指针。 任何类型的指针变量只能存储地址。
这个:
int* intPtr=60;
在intPtr
存储地址60
:没有int
赋值或intPtr
正在发生。 此时不存在int
变量。 编译器应该在此行发出警告。 任何顺从intPtr
尝试intPtr
可能导致崩溃。
当你写:
char* charPtr = "I can't understand why";
这意味着正在分配字符串“我无法理解为什么”的基址
charPtr因为字符串文字也是指向该字符串的指针。
它可以被视为:
这意味着,在charPtr中存储整个字符串的基址。现在,这就是您在代码中所做的。
char *charPtr="i cant understand why";
除此之外,如果您打印如下语句:
printf("%c","i cant understand why"[0]);//prints i printf("%c","i cant understand why"[2]);//prints c
这两个printfcertificate了我的概念,即字符串“我不能理解为什么”本身就是指向存储字符串的char数组的指针。
初始化intPtr
以指向绝对内存地址60
。 这里没有后盾店。
由于您没有取消引用指针本身,因此您永远不会尝试读取地址60
,这可能会导致程序崩溃,具体取决于环境。
相反,您将指针值传递给printf
,它将几乎任何东西作为参数传递,并解释您在格式字符串中指定的值。 在您的情况下,它将解释指针的地址而不是指针值。 地址为60
以便显示。 如果你使用*intPtr
而不是它可能会崩溃。