關於指針數組的初始化的一個問題?
感謝各位的回答,在此謝謝大家,大家的回答很好地解答了我的疑惑!
更新一下:問題描述錯誤了,應該是const int*p[3]={1,2,3}為什麼不能初始化?不好意思啦,另外,經提醒%c改為%s1.const char * p[3]={"a","b","c"}能初始化成功,但const int *p[3]={1,2,3}卻不能初始化?2.const char*p[3]={"a","b","c"};printf("%s",p[i])為什麼列印出的是字元的值,p[i]中難道不是存的地址嗎 ?
第一個:因為int不能轉char*,雖然它可以轉char第二個:這個printf要用%s
1.const char * p[3]={"a","b","c"}能初始化成功,但const int *p[3]={1,2,3}卻不能初始化?
因為:"a","b","c"這些字面值的類型本身就是const char*,而1,2,3這些字面值的類型是int,int是不能賦值給const int *的,除非你強轉。2.const char*p[3]={"a","b","c"};printf("%s",p[i])為什麼列印出的是字元的值,p[i]中難道不是存的地址嗎 ?因為:p[i]的類型是const char*,你用「%s"輸出時,是輸出這個字元串的內容。如果你想輸出p[i]中保存的地址,用這條語句:printf("%p",p[i])重點是,你要理解什麼是指針數組,什麼是數組指針。1 const int*p【】= {(int*)1,。。。}試試。意義何在2 %s要的就是字元串地址來輸出字元串,你恰好傳進來地址,正好。若有輸出地址用%p或%d
C里字元串其實是字元數組。"ahaha"編譯之後字元串本身存在.data segment,原處只留下"ahaha"的開頭在.data里的地址。所以字元串都是char *,因為這是字元串開始的地址。printf的%s要的就是這個開始地址,然後再一路向後輸出直到遇到一個" "為止,這個" "編譯器會自動給你加在"ahaha"的末尾。1裡面你想要的是整數數組吧,那麼類型就應該寫成const int[3]。
第一個問題,你寫的
const char * p[3] = {"a", "b", "c"}
不是字元數組,是個字元指針數組,數組p中存放著的是字元指針,其中第一個指針指向一個c風格的字元串"a"也可以看成指向一個字元數組,數組中的內容是
{"a", " "}
使用字元串字面量可以初始化字元指針數組,字元串字面量就是一個指向字元串的指針,他的值和上面那個數組中的『a"的地址是相同的。
第二個問題,使用%s輸出的時候,看到一個字元指針,就會自動將從這個指針指向的地址直到遇到" "之間的字元輸出出來,所以只提供第一個字元的指針就夠了。你上面的字元串數組"a"之後就是』 "了,自然輸出』a"就結束了。其他字元串同理。const int*p[3] 是一個指針數組,也就是數組內每個元素都是指針, 題主用三個int初始化當然不行了。
樓主可能基礎知識沒看明白,int*p[3],它首先是一個數組,有3個元素,每個元素是一個指向int型的指針。所以你初始化的時候應該放指針在裡面。你可以和int (*p)[3]比較,它首先是一個指針,指向一個能存放3個int元素的數組。你可以理解為是一個二維數組。
同理const char * p[3],它首先是一個數組,這個數組能存放3個元素,每個元素都是指向char的指針。實際上就是字元串。而c,字元串常量本身就是指針。所以"a","b","c"你能初始化成功。
本人也是菜鳥,正在讀c primer plus十六章,字元串這個坑我也踩過,所以記得比較深。這些知識在本書都有詳細解釋,雖然很多大牛嫌這本書啰嗦,但是我讀過來表示,凡事作者羅里吧嗦重複寫的內容,一定是很多新手容易踩坑的地方。我十分推薦題主靜下心來讀一遍,等你也覺得作者啰嗦了,你就差不多把c的基礎知識打紮實了。首先,其實字元串自己就是個const char*。
《C和指針》裡面說過,就是"ji"這個都是指針,你可以直接
printf("%c", "ji"[0]);
這樣用。
而int顯然和const int*不一樣。第二個問題,關於地址%s這個格式化符的話,實際上編譯器做了個處理,把那個地址(字元串就是地址)從開始做解引用,直到" "。實際上ca[i]是什麼呢?看這樣的栗子int main() {
const char* ca[3] = { "ji","lian","yong" };
printf("%c
", "ji"[0]); 看結果:
for (const char* pc : ca) {
printf("%s %X
", pc, reinterpret_cast&
for (int i = 0; i &< strlen(pc);++i) {
printf("%c %X
", pc[i], reinterpret_cast&
}
printf("
");
}
getchar();
return 0;
}
之後對於每個字元串,你還可以看出,每個字元串首地址的前面空出來了一塊內存,那個是用來存相關信息的。
你看看第二個如果要輸出指針保存的地址就把%s 改為%p,%p表示輸出該指針指向的字元串。
第一個你把雙引號改成單引號試試。然後,自己琢磨琢磨輪子哥給了解,但沒有給為什麼呀,希望你真的能明白究竟是為什麼
基礎C知識吧,我建議你了解清楚一下基本的數據結構及長度。第一個問題,指針不能直接用int型去初始化,長度一般不同。 第二個問題,printf要的就是指針來輸出具體內容,可以去好好看看printf函數。
1. 你用三個C風格字元串初始化三個const char* 這是允許的,char*被視作字元串。然而,const int*不能這樣初始化。
2. 同上,char*被看做字元串,p[i]表示字元串的起始地址,會一直向後找到 作為完整的字元串列印。如果你想列印地址,改為printf("%p", p[i])。
問題二應該用d%吧 列印一個數字 不就把地址打出來了
這題難道不應該去百度知道問嗎?
第一個1,2,3不是地址,指針數組你應該賦予每個元素地址。第二個你要輸出地址用%d就可以。
你這個對應邏輯不對哦,1是int,但是"a"不是char。"a"才是char
1.const char * p[3]={"a","b","c"}能初始化成功,但const int *p[3]={1,2,3}卻不能初始化?
第1個p:p是1個數組,有3個元素,每一個元素的類型是const char*, 所以後面的初始化可以成功。同理第2個是無法初始化的,因為1,2,3的類型不是(或者無法自動轉化成為)const int*。2.const char*p[3]={"a","b","c"};printf("%s",p[i])為什麼列印出的是字元的值,p[i]中難道不是存的地址嗎 ?這個其實要看printf的實現。約定是如此。1 2 3不是地址
推薦閱讀:
※為什麼C++的庫函數的定義會這麼複雜?
※如何才能寫出沒有bug的程序?
※為什麼OJ上有些人提交的代碼運行那麼快? 有人總結這些技巧么
※如何解決 C++ 代碼不能打開提示有一個錯誤的問題?