有一件事总让我困惑,角色指针。 经过四年多的努力,我再次徘徊在c。
以上述案例为例。char
指针为何以这种方式运行?当指针指向什么都没有时,我们怎么能直接解决指针的内容呢?或者它就像char指针存储除地址之外的东西!
#include <stdio.h>
#include <stdlib.h>
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;
在没有得到地址的情况下偷偷摸摸(或者被视为地址,如果是这样,为什么这在前一种情况下是不可接受的)指针对象!
我想我在这里错过了什么,但是嘿!你猜怎么着 ?他们告诉我在SO搜索!
编辑:将char指针指向的地址赋予int指针也会引发错误!
int8_t* intPtr= (int8_t*)0x80485c8 ; // works without casting too ! I guess addresses are acceptable.
取消引用它将给出一个等于字符串的第一个I
的值。这是一个很好的做法,或者对此存在任何其他解释,而忽略了它们的字节位大小分配,例如int可以容纳一个char所以..?
正如hmjd指出'初始化语法'是问题所在!我编写自己的代码没有问题,但修改某人的代码时会出现问题!
答案 0 :(得分:6)
当指向什么都没有时,我们如何直接解决指针对象的内容,或者它是否像char指针一样存储除地址之外的东西!
我认为混淆是初始化语法。这样:
char* charPtr="I cant understand why";
不会取消引用charPtr
。它相当于:
char* charPtr;
charPtr = "I cant understand why";
两个代码段都将字符串文字"I cant understand why"
的地址存储到charPtr
。没有解除引用指向任何事物的指针。任何类型的指针变量都只能存储地址。
此:
int* intPtr=60;
在60
中存储intPtr
的地址:没有int
分配或引用正在发生。此时不存在int
变量。编译器应该在此行发出警告。任何尊重intPtr
的尝试都很可能导致崩溃。
答案 1 :(得分:4)
在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??
字符串文字也是数组表达式,在大多数情况下,类型为“{-1}}的N元素数组”的表达式将转换为“{{1的指针” “,”它的值将是数组的第一个元素的地址(例外情况是数组表达式是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
您正在使用60初始化指针值,而不是将其设置为指向值为60的匿名整数:
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??
地址60很可能不是有效地址,因此尝试取消引用int* intPtr = 60;
很可能会导致未定义的行为。
你写过像
这样的东西吗?Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
intPtr 0xffbe4004 0x00 0x00 0x00 0x3C
那么你会遇到这样的情况:
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
直接分配给value
。 value
的类型被视为x
。请注意,您应在
value
沿着“从没有强制转换的整数制作指针”这一行。
答案 2 :(得分:3)
当你写:
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
这两个printf证明了我的概念,即字符串“我无法理解为什么”本身就是指向存储字符串的char数组的指针。
答案 3 :(得分:1)
您的intPtr
已初始化为指向绝对内存地址60
。这里没有后盾店。
由于您没有取消引用指针本身,因此您永远不会尝试读取地址60
,这可能会导致您的程序崩溃,具体取决于环境。
相反,您将指针值传递给printf
,它将几乎所有内容作为参数传递,并解释您在格式字符串中指定的值。在您的情况下,它将解释指针的地址而不是指针值。地址为60
,以便显示。如果你使用了*intPtr
,它可能会崩溃。