2009-11-04 433 views
2
char* p = "hello world"; 

程序員通常將一個變量的地址賦給一個指針。但在上述情況下,指針指向哪裏?這個指針做了什麼?

,並在世界上是什麼

int x =42; 
int* p= &x; 
int ** r = &p; 
+1

不,*符號通常不會將變量的地址分配給指針。它總是將一塊內存的地址分配給一個「指針變量」。在某些情況下,地址是一段數據的地址,在其他情況下,它是包含變量值的一段內存的地址。如果您瞭解了一些關於在彙編程序中編程的知識,並且使用像DOS調試命令這樣的基本調試程序來調試機器代碼的執行,那麼理解C的這一方面會更容易。 – 2009-11-04 07:25:37

+7

這是怎麼回事,在這裏連續發表你的作業題目? – DVK 2009-11-04 07:26:40

+0

「克里斯,我誤解了我的問題**」 - 你甚至讀過答案嗎?變量的名稱和類型不會改變發生了什麼的想法。 – Groo 2009-11-04 07:36:18

回答

14

它指向包含ASCII序列hello world的程序只讀存儲器中的區域(通常在程序的機器碼本身中)。與此相比,:

char p[] = "hello world"; 

其產生的12個char S中的堆棧上的陣列,這是可以修改的,就像任何其他變量,以及:

char *p = strdup("hello world"); 

其產生的12 char秒的陣列在堆上,並且將p設置爲指向這個可讀的堆可寫入的空間的存儲器。

至於你(完全無關)的第二個問題:

int** r = &p; 

簡單比它的外觀,雖然這也是不好的。 &p地址的p。所以,如果我們這樣做:

int x; 
int *y = &x; 

然後將鼠標指針y變量x,所以分配給*y改變x(反之亦然)。我們可以對任意複雜類型做到這一點:

int *x; 
int **y = &x; 

現在y仍指向x一個指針,但x也是一個指針。因此,在您的示例中,r是指向指向int的指針,它的值是p(指向char的指針)的地址。但是,這樣做不好,因爲許多平臺在從char *類型轉換爲較大的指針類型時都存在對齊問題。

+0

我記得讀過關於字符串文字的東西會自動轉換爲一個臨時的全局變量。這是你在第一個例子中提到的嗎?謝謝 – user133466 2009-11-04 07:17:37

+0

字符串文字只是程序中的一系列只讀數據,就像數字常量和其他類似的東西一樣。 'char * p =「string」'只是將指針'p'指向那部分數據。 – 2009-11-04 07:21:23

+0

爲什麼要創建一個指針指向「壞」的指針?它是改變函數輸入指向堆的唯一方法。 – 2009-11-04 08:45:57

3

的字符串常量「Hello World」的必須駐留在某個應用程序,並在運行時加載到內存中。通常這是在可執行文件的數據部分。指針p指向內存中的這個地址。

第二個例子簡單地取p的地址。鑑於p在堆棧上,它將成爲當前堆棧的地址。

0

p指向以NUL結尾的字符串的第一個字符。 r指向一個指針......也就是說它指向一個指向一個整數的持有指針的位置。

1

當聲明一個指針時使用的星號表示它只是一個指針(它是它的類型化合指定符的一部分),並且不應該與取消引用操作符(也是星號)混淆。

如果要訪問它返回的值,則必須在它之前加上一個雙星號。

-1

p是存儲有"hello world"的存儲器地址,所以存儲器p'address具有地址位置...

int** r = &p;

所以r是到該地址的參考...有點兒弄亂

2

插圖可能會有所幫助。鑑於以下聲明:

char *s = "hello world"; 
int x = 45; 
int *p = &x; 
int **r = &p; 
char q[] = "hello world"; 

承擔下列存儲器映射(地址和佈局完全是任意的,並不意味着代表任何真實世界的架構):

 
       0x00 0x01 0x02 0x03 
    0x00008000: 'h' 'e' 'l' 'l' 
    0x00008004: 'o' ' ' 'w' 'o' 
    0x00008008: 'r' 'l' 'd' 0x00 
    ... 
s: 0x01000000: 0x00 0x00 0x80 0x00 
x: 0x01000004: 0x00 0x00 0x00 0x2D 
p: 0x01000008: 0x01 0x00 0x00 0x04 
r: 0x0100000C: 0x01 0x00 0x00 0x08 
q: 0x01000010: 'h' 'e' 'l' 'l' 
    0x01000014: 'o' ' ' 'w' 'o' 
    0x01000018: 'r' 'l' 'd' 0x00 

字符串「你好世界「是包含靜態範圍的charconst char,在C++中)的12個元素的數組,這意味着在程序啓動時分配內存並保持分配狀態直到程序終止。確切地說,字符串文字在內存中的位置取決於平臺,但最好假設內存是不可寫的(即,不能用strcpy()strcat()sprintf()等來更改它的內容)。該語言標準明確指出試圖修改字符串文字會導致未定義的行爲。

char *s = "hello world"; 

限定s作爲指針以炭與文字的地址(0x00008000在本例中)進行初始化。

int x = 45; 

x定義爲一個整數,並與值45(16進制數2D)進行初始化。

int *p = &x; 

p定義爲一個指針int和與x(0x01000004)中的地址進行初始化。

int **r = &p; 

r定義爲一個指針的指針爲int並用的p(0x01000008)中的地址進行初始化。

請注意,指針類型是不同的,並不總是兼容的。儘管sp,並且r都決心的32位地址值在這個特定的假設,他們有不同的類型不一定互換,即使他們都設置爲指向同一位置。一些平臺針對不同的指針類型使用不同的大小和表示。

最後,作爲一個額外的好處,我們有線

char q[] = "hello world"; 

其中q定義爲炭的12個元素的數組(從字符串文字的大小取尺寸被用來初始化)並使用字符串文字的內容對其進行初始化。