2012-10-13 193 views
4

我想了解指針是如何工作的,所以我創建了這個小程序。首先我創建一個p指針,它指向一個char。char和char *(指針)

的第一個問題是在這一點上。如果我創建一個指針,它的值是一個內存地址(如果我將它指向一個非指針對象),但這次在我的例子中是「哈哈」。爲什麼它在char *中以這種方式工作?而我怎麼能用cin >> p增加它的價值呢?

第二個問題是,我創建A Q炭,其在我創建它的點的* P指針的值。但它的價值和地址也是「h」,但爲什麼?它必須是這個char對象的內存地址!這是毫無意義:d(MinGW的 - GCC)

int main() { 
    char *p; 
    cin >> p;      //forexample: haha 
    char q = *p; 
    cout << "&q = " << &q << endl; //&q = h 
    cout << "q = " << q << endl; //q = h 
    return 0; 
} 

更多:如果我分配內存第一使用char [100]; char * p = a;那麼& q = h»ŢĹ,所以「h」有些亂七八糟。但它應該是一個內存地址!我的問題是,爲什麼它不是地址呢?

+1

這不是安全的。 'p'沒有任何內存供您輸入。 – chris

回答

5

思考的char* p;在內存中的地址。你沒有初始化這個指針,所以它沒有指向任何東西,你不能使用它。

要始終安全:
要麼初始化指針爲零:

char *p = 0; // nullptr in C++11 

或初始化一些自動

void foo() { 
    char a[100]; 
    char *p = a; 
} 

或全局內存:

char a[100]; 
void foo() { 
    char *p = a; 
} 

或獲取動態內存:

char* p = new char [100]; 

然後你可以使用P(如果不爲null)來讀取數據,並從P到讀...


爲了您的operator >> (std::istream&, char* p) misunderstaning。此運算符期望p指向某些內存(自動,全局,動態 - 無論如何) - 它不會自行分配內存。它只是從輸入流中讀取字符,直到空白並將其複製到p指向的內存 - 但p必須已經指向某個內存。


用於取地址爲char q;。當然,您可以輸入地址q&q,它的類型是char* p。但是&qp不同,而q=*p只是將p指向的第一個字符複製到q,它不能更改地址q - 其地址不可更改。對於cout << &q - operator << (ostream&, char* p)預計p點爲NULL結尾的字符串 - 和&q指向包含"H"內存,但是這是什麼字,沒有人知道後 - 所以你會在屏幕上得到一些垃圾。使用cout << q打印單個字符。

+0

所以,你說cin不分配內存,那麼我的「哈哈」在哪裏?指針如何包含整個字符串? q是一個簡單的字符變量,所以它可以包含p的任何字符,並且我沒有分配我的「哈哈」文本,所以這就是爲什麼我的「h」沒有內存地址?很明顯,但我有一個問題然後: 當我將字符複製到q(char q = * p),它不是真正的複製,它只是指向該數據,這是不分配?所以問題無處不在,我的哈哈文本沒有分配,所以我不能有任何地址? – Iburidu

+0

好的,我用int創建了一個程序,並且int已經被分配,我可以cout << p;它會寫回地址。程序簡短:「int a [10]; int * p = a; cin >>(char *)p; cout << p <<」,「<< atoi((char *)p);」 – Iburidu

+1

因爲你沒有賦予'p'任何值甚至'0' - 那麼它指向一些隨機地址。您在程序中將「哈哈」複製到一些隨機內存中 - 它可能會導致任何事情,這是未定義的行爲 - 甚至可能會導致向您的上司發送電子郵件,說明您有更好的工作 - 但也可能發生這種隨機內存沒有使用 - 所以它看起來像你的程序工作正常。 – PiotrNycz

0

你應該是這樣的:在你的程序的頂部

#include <iostream> 
using namespace std; 

。或者可以省略using並參考std::cinstd::cout

int main() { 
    char *p; 

p是一個指針,但是你有沒有初始化,所以它可以在任何地方或無處點。你需要對它進行初始化,例如:

p = new char[100]; 

...

cin >> p;      //forexample: haha 

這是確定如果你初始化p某處點 - 除了你可以溢出緩衝區它指向你是否輸入了太多的數據。對於這樣一個簡單的測試程序來說沒關係,但實際上你會想要採取措施來避免它。

char q = *p; 
    cout << "&q = " << &q << endl; //&q = h 

&qchar*類型,一個指針到char的。發送char*值到cout不會打印指針(存儲器地址)的值;它會打印它指向的字符串。 (雖然我得到一些奇怪的結果,當我跑我自己,我可能失去了一些東西)如果你想看到指針的值,將其轉換爲void*

count << "&q = " << (void*)&q << endl; 

(或者你可以使用的一個且該C++ - 特定鑄件;我不知道這是最好的)

cout << "q = " << q << endl; //q = h 

這裏q只是一個char,所以這個打印它作爲一個字符值:h

return 0; 
} 
+0

是的,在我的代碼上,我採取了前兩行,但它明顯,所以我沒有放在這裏。我明白了,但cout <<&q必須是cout << p然後,對吧?而不是。 &q =「h」和p =「haha」 – Iburidu

2

學習並永遠記住關於指針的第一件事是,確保爲他們分配內存,否則你的程序將無法正常運行。

如下來分配存儲器中,使得「CIN」可以寫用戶輸入到所分配的存儲器您的代碼實際上應修改:

int main() { 
    char *p = new char[1024];  // allocate memory so cin 
    cin >> p;      //forexample: haha 
    char q = *p; 
    cout << "&q = " << &q << endl; 
    cout << "q = " << q << endl; 
    return 0; 
} 

現在,字符指針是一個變量指向的位置內存中有一組字符(不一定是一個字符,可能不止一個,也可能不是特殊值null),而字符變量實際上只包含一個字符(不是一組字符)。

處理指針時的基本運算符是&(的地址)和*(值at)。 &檢索變量的地址,所以如果我們有[char q;]那麼[& q]將是一個字符指針。另一方面,*檢索給定指針的值,所以如果我們有[char * p;],那麼[* p]就是p指向的內存中的字符。

現在回到你的榜樣,內嵌用於說明

int main() { 
    // allocate a place of 1024 character in memory 
    // and let p points to that place 
    char *p = new char[1024];  

    // call cin to read input from the user and save 
    // it in memory at the location pointed to by p 
    // NOTE: cin would put an extra NULL character 
    // at the end to terminate the string 
    cin >> p;      //forexample: haha 

    // Now p would be pointing to a piece of memory like this 
    // [h] [a] [h] [a] [\0] 

    // use the value at operator to de-reference the pointer 
    // p, the result would be a single character which 
    // will be the first character in memory p is pointing at 
    char q = *p; 

    // printing the value of (the address of q) 
    // Note you have a problem here as cout will 
    // be handling the memory starting at the address 
    // of q as a string while it is not, so you 
    // will get a string starting with "h" and followed 
    // by whatever is there in memory by the time of execution 
    cout << "&q = " << &q << endl; 

    // printing the value of the character q 
    cout << "q = " << q << endl; 
    return 0; 
} 

意見,我希望它可以幫助

+0

是的,很明顯,如果我將位置分配給p,那麼它會向&q寫入「h和一些亂碼」,但是如果我不將位置分配給p, h「,與* p相同。所以q =&q? :D但我認爲PiotrNycz是正確的,這是因爲「哈哈」沒有分配,所以它沒有內存地址,所以&q(這是p)不能指向任何地方,但爲什麼它停止後「h 「 然後? – Iburidu

+0

@Iburidu在您的機器/編譯器上發生的特定情況不是一般情況。將數據存儲在未分配的內存空間中的結果是不可預知的。在你的情況下,內存已經滿了零,所以打印字符串開始&q恰好打印出「h」只是偶然的,沒有更多。 – Hisham

+0

好吧,我通過添加char a [100]來分配; int * p = a;但爲什麼p ==「哈哈」,如果它應該是一個內存地址(&a [0])? – Iburidu