2012-08-29 90 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的證明我的理念是,字符串「我無法理解爲什麼」本身就是一個指向字符數組在其中字符串正在被存儲。