指针初始化为什么?

时间:2012-08-29 09:32:56

标签: c pointers character function-pointers

有一件事总让我困惑,角色指针。    经过四年多的努力,我再次徘徊在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指出'初始化语法'是问题所在!我编写自己的代码没有问题,但修改某人的代码时会出现问题!

4 个答案:

答案 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直接分配给valuevalue的类型被视为x。请注意,您

上收到警告
value

沿着“从没有强制转换的整数制作指针”这一行。

答案 2 :(得分:3)

当你写:

 char* charPtr = "I can't understand why";

这意味着字符串“我无法理解为什么”的基地址被分配给

charPtr,因为字符串文字也是指向该字符串的指针。

可以视为:

the concept of string stored in an char array

这意味着,在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,它可能会崩溃。