2012-08-29 61 views
6

一件事,一直困惑我,字符指针。 诘这四年我又缠绵成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和它从哪里获得存储在哪里?

撇开字符指针和malloc的,我以为指针的基本想法是得到一个地址指向!

为什么这些案件

*intptr = 60 ; // should be setting the pointee's value to 60 
    intptr = 60 ; // sets the address 

掷编译错误而

int* intPtr=60; 

偷偷在没有得到一个地址(或者是作为地址60,如果是这样,为什么这不能接受不前者的情况下)的指出!

我想我在这里的东西,但嘿!你猜怎么了 ?他们告诉我在SO搜索!

编辑:给指向的地址的字符指针为int的指针也会引发中没有错误!

int8_t* intPtr= (int8_t*)0x80485c8 ; // works without casting too ! I guess addresses are acceptable. 

解引用它会给等同于字符串的第一个I值。是一个很好的做法或有任何其他的解释存在于这个离开了thier字节位大小分配,如int可以支持一个char所以.. ?

正如hmjd指出'初始化语法'是问题!编写我自己的代码没有问题,但修改某人的代码时出现问题!

+0

真的很难弄清楚你究竟在问什么。指针是一个变量,其值通常是另一个变量的地址。 –

+0

*我想我错过了这里的东西*实际上,好的C编程书籍/教程。你问了很多常见问题。 –

+0

@DavidSchwartz是的!这也是我的基本想法:)但是这里发生了什么? – Borrito

回答

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?? 

的字符串文字也是阵列表达,并且在大多数情况下型“T N元件阵列”的表达将被转换为键入“指向T”的指针,其值将是第一个e的地址(数组表达式是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并分配给value的结果;它将value直接分配给xvalue的类型被视为T *。请注意,您应该

int *intPtr = 60; 

沿着“做从整数指针,未投”的线路越来越警告。

6

我们如何直接处理指针对象的内容,当它指向什么也不是它是否像char指针存储地址以外的东西!

认为混乱是初始化语法。此:

char* charPtr="I cant understand why"; 

不解除引用charPtr。它等效于:

char* charPtr; 
charPtr = "I cant understand why"; 

两个代码片段存储字符串字面"I cant understand why"charPtr的地址。没有取消引用指向没有任何发生的指针。任何类型的指针变量只能存储一个地址。

此:

int* intPtr=60; 

60intPtr的地址:int转让或deferencing正在发生。此处没有int变量存在。编译器应该在这一行发出警告。任何试图尊重intPtr的企图很可能会导致崩溃。

+0

我认为你是对的!他认为“a = b;”意思是“将变量a的值设置为b的值”。但它实际上的意思是“设置变量a,使其值为b”。如果x的值是2,'x = 3;'试图将变量'x'设置为3,它不会设置2到3.(OP缺失的基本概念是左值和右值) –

+0

@ hmjd所以char指针在这方面至少与其他指针有所不同,是吗?你说int * intPtr = 60;将地址60存储在intPtr中,所以如果我输入一个有效地址并将其解引用,我会得到值而不考虑类型吗?我认为更新这个问题会更好。 – Borrito

+0

@Borrito,no。这里的区别是你正在分配的初始值。对于char *',你正在分配一个有效的地址。对于'int *',你不是。如果你'int i = 4; int * intPtr =&i;'然后'intPtr'将具有'i'的地址,并且遵守'intPtr'是合法的。 – hmjd

1

您的intPtr被初始化为指向绝对内存地址60。这里没有后台商店。

由于您不是取消引用指针本身,您也不会尝试读取地址60,这可能会导致程序崩溃,具体取决于环境。

相反,您将指针值传递到printf,它将几乎所有东西都当作参数并按照您在格式字符串中指定的值解释值。在你的情况下,它将解释指针的地址而不是指针值。地址是60,以便显示。如果您使用*intPtr,它可能会崩溃。

2

当你写:

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的证明我的理念是,字符串“我无法理解为什么”本身就是一个指向字符数组在其中字符串正在被存储。