關於指針數組的初始化的一個問題?

感謝各位的回答,在此謝謝大家,大家的回答很好地解答了我的疑惑!

更新一下:問題描述錯誤了,應該是const int*p[3]={1,2,3}為什麼不能初始化?不好意思啦,另外,經提醒%c改為%s

1.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&(pc));
for (int i = 0; i &< strlen(pc);++i) { printf("%c %X ", pc[i], reinterpret_cast&(pc + i));
}
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++ 代碼不能打開提示有一個錯誤的問題?

TAG:C編程語言 | C | 指針 |