前言:今天覆習結構體陣列知識的時候,順手做了一道程式設計題,沒想到發現了大問題。「指標陣列」還是掌握的不好。這篇部落格就從那道我發現問題的題目入手,講解一下學習過程中踩過的坑和自己的課後查漏補缺。
原題目:有3個候選人,每個選民只能投票選乙個人,要求編乙個統計選票的程式,先後輸入備選人的名字,最後輸出各人投票結果。(參見譚浩強《c程式設計》第四版p300例9.3)
書上思路:設立乙個結構體陣列,陣列中包含3個元素,每個元素的資訊應包括候選人的姓名(字元型)和得票數。輸入被選人的姓名,然後與陣列元素中的「姓名」比較,如果相同,就給這個元素中的「得票數」成員的值加1.最後輸出所有元素的資訊。
**:
#define _crt_secure_no_warnings 1
#include#includestruct person
;int main()
, , };//三位候選人資訊
printf("輸入名字:");
char name[20];//定義字元陣列
for (int i = 0; i < 10; i++)
}} for (int i = 0; i < 3; i++)//遍歷結構體陣列,輸出每位候選人的姓名和票數
return 0;
}
書中是採用定義乙個字元陣列,從而不斷輸入10個候選人名字的。我想的是採用指標陣列的形式:定義大小為10的指標陣列,存放輸入的10個人的姓名,其他原理同上。
關鍵**如下
char* name[10];//定義大小為10的指標陣列,存放輸入的10個人姓名
for (int i = 0; i < 10; i++)
}}
然後發現程式崩潰
問題就出在了scanf("%s", name[i]);這句上。我們想象的是指標陣列char* name[10]中每一塊內容都存放的是char*指標,這個指標指向每個字串的首字元位址,所以name[0]、name[1]......的型別都為char*,所以這裡輸入的時候不加「&」符。但是這裡踩了乙個大坑,也是程式設計過程中的乙個易錯點:當字串以指標的方式訪問時,如char*p="abc",這裡定義了指標p,p中存放字串的首位址,abc其實是儲存在常量區的,所以只能「讀」不能「寫」;其次,按目前的宣告,name是乙個大小為10的指標陣列,sizeof(name)=40,說明它只分配了容納指標的40個位元組,陣列中的元素其實都是野指標,並沒有指向合法可用的記憶體,因此在寫入字串之前一定要要動態分配記憶體,並將指標指向新分配的記憶體。(如下圖所示)
再用乙個更具體的例子說明問題(這個**是其中一位層主的回答
#include#define n 3
#define len 10
void main()
{//輸入n個字串
答:上面的**是通過scanf("%s",&str[i]);將字串寫入的實際上它並沒有寫入每次字元指標指向的空間(6161,6262,6363指向的地方),而是寫入了存放字元指標本身所佔的4個位元組中(即f7c4,f7c8,fc77),當所以每個空間只能寫入4個位元組的字串;當輸出時,採用 printf("%s\n",str+i);的方式進行輸出,也就是&str[i],先找到&str[0]的位址f7c4,然後輸出該位址存放的字串,直至遇到『\0』;然後再找到&str[1]的位址f7c8,輸出該位址存放的字串,直至遇到『\0』;依次進行。
以情況一為例:位址f7c4中存放的是乙個char*型別的指標,佔四個位元組,**中把「aa」字元寫入了這四個位元組當中,也就是占用了3個位元組,輸出字串的時候程式找到&str[0]的位址f7c4,遍歷字串,直至遇到\0,所以輸出「aa」截止,「bb」和「cc」的正常輸出也是同理。
但是情況二和三就不一樣了。以情況二為例來說,「aaaaa」一共佔據6個位元組,可是&str[0]的位址f7c4時存放指標的空間,只有4個位元組,於是在寫滿這四個位元組後,又向下乙個空間&str[1]的位址f7c8中寫入剩下的乙個a和『\0』,參見-->
所以最終位址f7c4所在空間的4個位元組被「bbbb」佔據,最後乙個b和『\0』分別寫入了&str[2]的位址f7cc所在空間的第乙個和第二個位元組中-->
最後再找到&str[2]的位址f7cc,寫入「ccccc」,同樣,這裡的前兩個位元組又被「cc」覆蓋掉-->
最終&str[2]的位址f7cc寫入了「cccc」,最後乙個『c』和『\0』寫入了&str[3]的位址f7d0空間的前兩個位元組-->
這也就解釋了為什麼會出現這樣的輸出。
總結:網上查詢的結果不一定對,一定要親自驗證,除錯**弄懂。
學習WebService過程中遇到的錯誤歸總
1 org.apache.cxf.endpoint.serverimpl cannot be cast to com.ws.service.ilove 這個錯誤主要因為使用的factory不正確.serve ctorybean,jaxwsserve ctorybean 用於伺服器端.前者針對pojo...
構建fabMap過程中可能遇到的錯誤
1.when opencv2.4.9 is not installed,the system has opencv2.4.8 pre installed in usr lib x86 64 linux gnu and usr include,where there is no opencv nonf...
在使用Kafka過程中遇到的錯誤
問題一 用kafka命令傳送訊息時候,一直報warn error while fetching metadata with correlation id 0 原因 由於主題沒建立導致的,生成是禁止自動建立的。問題二 created producer rdkafka producer 1 log 3 ...