2014-03-06 95 views
-1

進出口新的C語言編程,我想知道如何做一個指針常量從常變量不同,在這種情況下:常量指針VS常變量

#include <stdio.h> 
int main(void) 
{ 
    int cnt = 0;   

    char val; 
    char mystr[20] = 「hello there!」; 
    char *p_str2, str2[20] = 「zzzzzzzzzzzzzzzz」; 
    char* p_mystr = mystr; 

    p_str2 = str2; 

    while (*p_mystr != 0x00) 
    { 
     val=*p_mystr++; 
     cnt++; 
    } 

    return 0; 
} 

也,如何mystrmystr[2]不同(什麼數據類型是每個變量)並且有什麼不對的p_mystr = mystr[2];可以寫得更好(即:爲什麼*p_mystr= mystr[2];正確)?

+5

您非常需要[this](http://www.c-faq.com/aryptr/index.html)! – haccks

+0

也考慮http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c – Coconop

+0

這裏沒有「指針常量」或「常量變量」,所以你的第一個問題是不清楚的。 – interjay

回答

0

除非它是sizeof的操作或一元&運算符,表達式的類型「T」的N元素數組將被轉換爲「指向T的指針」類型的表達式,並且該表達式的值將是該數組的第一個元素的地址。結果不是左值,這意味着它不能成爲任務的目標。

所以,給出的聲明

char mystr[20] = "hello there!"; 

下面都是真:

Expression  Type   Decays to  Result 
    ----------  ----   ---------  ------ 
     mystr  char [20]  char *   address of mystr[0] 
     &mystr  char (*)[20] n/a   address of mystr 
     *mystr  char   n/a   value of mystr[0], or 'h' 
    mystr[i]  char   n/a   i'th character 
    &mystr[i]  char *   n/a   address of mystr[i] 
sizeof mystr  size_t   n/a   20 (number of bytes in array) 

數組的地址是相同的數組的第一元素的地址(沒有存儲是預留一個mystr變量與陣列元素本身分開的),所以表達式mystr,&mystr&mystr[0]都返回相同的,但表達式的類型不同; mystr&mystr[0]都具有類型char *,但是&mystr具有類型char (*)[20]或「指向20元素陣列的char」。

str2的結果相同。

鑑於申報

char *p_mystr; 

我們得到以下

Expression  Type  Result 
    ----------  ----  ------ 
     p_mystr  char *  value in p_mystr 
     *p_mystr  char  value of character pointed to by p_mystr 
     &p_mystr  char **  address of p_mystr variable 
sizeof p_mystr  size_t  number of bytes in pointer value 

p_str2表是一樣的。

現在這是一個匹配類型的問題。 p_mystr = mystr可以工作,因爲這兩個表達式都有char *; p_mystr指向mystr[0]。同樣,*p_mystr = mystr[2]工程,因爲這兩個表達式都有類型charval = *p_mystr++相同,雖然在這種情況下注意*p_mystr++被解析爲*(p_mystr++);該增量將應用於指針值,而不是字符值。

請注意,像p_mystr = &mystr;這樣的表達式應該會爲您提供診斷,以確定類型不匹配。

您的問題標題提到const指針和變量,雖然它不出現在問題主體中。基本上,任何類型的T

T *p0;     // p0 is a non-const pointer to non-const T 
const T *p1;   // p1 is a non-const pointer to const T 
T const *p2;   // p2 is a non-const pointer to const T 
T * const p3;   // p3 is a const pointer to non-const T 
const T * const p4; // p4 is a const pointer to const t 
T const * const p5; // p5 is a const pointer to const t 

能分解爲:

  • 您可以寫信給p0(改變它指向別的東西)和*p0(改變的事情被指向的);
  • 您可以寫信給p1p2(改變它們指向別的東西),但你不能寫入*p1*p2(不能改變的事情被指向的);
  • 你不能寫p3(不能改變它指向別的東西),但你可以寫*p3(改變指向的東西);
  • 您不能寫信給p4p5(不能將它們更改爲指向其他內容),也不能寫入*p4*p5(不能更改指向的內容)。

所以,如果你宣佈類似

const char *cptr = mystr; 

你無法通過cptr變量修改mystr內容,即使mystr未聲明const本身。

注意,試圖走另外一條路,比如

const int foo = 5; 
int *fptr = (int *) &foo; 
*fptr = 6; 

調用未定義的行爲;它可能會或可能不會工作,具體取決於實現(語言定義允許實現將const限定的對象放在只讀存儲器中)。


1. 如果p_mystr指向某處有效,也就是說。

0

變量mystrstr2都是存儲在堆棧中的字符數組。除了用於初始化字符數組的字符串文字以外,這裏沒有任何「常量」。


p_mystr是一個指針,mystr[2]是一個字符。 其中是你的*p_mystr= mystr[2];應該是?最好不要之前p_mystr的初始化到一個有效的地址。

0

你剛纔問了一口!

  1. 指針與簡單數據類型(char *與char相比)是一種非常不同的類型。一個字符只有一個值,例如'一個'。你可以將一個指針看作是一個內存地址 - 也就是說,進入內存地址0x0123F1A,並把你在那裏找到的東西當作char。指針可能會很棘手,讓你頭腦發熱,所以值得一讀。 here
  2. mystr是一個字符數組。在某些方面,它的行爲就像是指向數組中第一項的指針,但它確實是一種獨特的類型。 mystr [2]具有char類型 - 它是在數組中的索引2處發現的char(即數組索引從0開始的第三個字符)。
  3. p_mystr = mystr沒有任何問題 - 從char數組分配給char型指針是安全的,其含義是使指針指向數組中的第一項。
  4. * p_mystr = mystr [2]的意思是別的。 *運算符的意思是「值指着」,所以這句話的意思是「在p_mystr指向的內存地址,複製的字符myStr中[2]」