二維數(shù)組初始化和一維數(shù)組相似,不過二維數(shù)組可以忽略行數(shù)(即第一個(gè)括號(hào)里的數(shù)字),但是不能忽略列數(shù)(即第二個(gè)括號(hào)里的數(shù)字)。因?yàn)槲覀兛梢酝ㄟ^第二個(gè)括號(hào)中的數(shù)字和數(shù)組中一共的元素個(gè)數(shù)可以推斷出行數(shù),所以可以忽略列數(shù)。但是反過來是不能的,所以要注意不能忽略第二個(gè)中括號(hào)里的內(nèi)容。
二維數(shù)組的存放順序是按行存放的,先存放第一行的元素,再存放第2行的元素。
-
二維數(shù)組作為函數(shù)參數(shù),在被調(diào)函數(shù)中不能獲得其有多少行,需要通過參數(shù)傳入。(這一點(diǎn)和一維數(shù)組是一樣的,在數(shù)組作為參數(shù)的過程中,會(huì)被認(rèn)為是指針,即8個(gè)字節(jié))
void test(char cs[2][3]) { int row = sizeof(cs); printf("row = %zu\n", row); } 輸出結(jié)果: row = 8但是二維數(shù)組作為函數(shù)參數(shù),在被調(diào)函數(shù)中是可以計(jì)算出二維數(shù)組有多少列的。
void test(char cs[2][3]) { size_t col = sizeof(cs[0]); printf("col = %zd\n", col); } 輸出結(jié)果: col = 3所以在這里總結(jié)一下:如果二維數(shù)組作為函數(shù)的參數(shù),在傳遞的過程中被認(rèn)為是指針,所以如果在被調(diào)函數(shù)中用sizeof直接計(jì)算數(shù)組共有多少行總是會(huì)得到8,因?yàn)閿?shù)組被當(dāng)作了指針。但是在被調(diào)函數(shù)中,如果我們用sizeof計(jì)算這個(gè)數(shù)組的某個(gè)元素,那么相當(dāng)于計(jì)算的是數(shù)組里的數(shù)組,所以是可以得到準(zhǔn)確的列數(shù)的。
-
字符串:
- 初始化
- char myString[9] = “hello"; //在內(nèi)存中以“\0”結(jié)束, \0 ASCII碼值是0
- char myString1[9] = {‘h’,'e’,'l’,’l’,’o','\0'};
- char myString2[9] = {‘h’,'e’,'l’,’l’,’o’, 0};
- char myString3[9] = {‘h’,'e’,'l’,’l’,’o’}; //靜態(tài)數(shù)組如果沒有賦值默認(rèn)就是0,0就相當(dāng)于\0
- 初始化
\0是字符串的標(biāo)志。
\0是字符串結(jié)束的標(biāo)志。
“ “ 一定是字符串。
字符串的本質(zhì)是數(shù)組,不過最后一個(gè)元素的\0。(可以看到初始化里面第2,3,4例子)
char myString4[] = {‘h’,’e’,’l’,’l’,’o’}; 不是字符串而是普通的數(shù)組。這與初始化里的第4條相似,但是是不同的。初始化第4條的例子前面規(guī)定包含了9個(gè)元素,后面賦值了5個(gè),相當(dāng)于部分初始化,所以后面會(huì)自動(dòng)補(bǔ)0,那么相當(dāng)于有了\0,所以是字符串;而在本例中,并不會(huì)自動(dòng)補(bǔ)充0,所以這就是一個(gè)普通的數(shù)組。
總結(jié)就是如果想方便的得到字符串,那么直接用”"即可,比如:char myString[] = “hello”;如果想用字符數(shù)組來得到字符串,需要在最后加上\0。
-
字符串輸出:
-
char myString[] = “hello";
printf("%s\n", myString);
-
但是注意這個(gè)問題:
char myString[] = {'h', 'e', 'l', 'l', 'o' '\0'}; char myArray[] = {'j', 'o', 'y'}; printf("myArray = %s\n", myArray);%s的本質(zhì)是根據(jù)首地址逐個(gè)輸出元素直到遇到\0。前面提高過變量尋址由大到?。‥xcel表相當(dāng)于myArray在myString上面,地址比myString要?。?,所以輸出完myArray后沒遇到\0將會(huì)繼續(xù)輸出緊挨著的內(nèi)存中的內(nèi)容,即myString中的元素,直到遇到\0。所以結(jié)果為joyhello。
-
-
字符串輸入:
-
char ch[10];
scanf("%s",ch);
注意:
- 對(duì)一個(gè)字符串?dāng)?shù)組, 如果不做初始化賦值, 必須指定數(shù)組長度
- ch最多存放由9個(gè)字符構(gòu)成的字符串,其中最后一個(gè)字符的位置要留給字符串的結(jié)尾標(biāo)示‘\0’當(dāng)用scanf函數(shù)輸入字符串時(shí),字符串中不能含有空格,否則將以空格作為串的結(jié)束符。
-
-
字符串?dāng)?shù)組:
- char myArray1[2][10] = { {‘h’,'e’,’l’,’l’,'o','\0'}, {‘w’,’o’,'r’,’l’,’d','\0'} };
- char myArray2[2][10] = { {“hello"}, {“world"} };
- char myArray3[2][10] = { “hello", “world" };
-
指針為什么要區(qū)分類型:
在同一種編譯器環(huán)境下,一個(gè)指針變量所占用的內(nèi)存空間是固定的。比如,在16位編譯器環(huán)境 下,任何一個(gè)指針變量都只占用8個(gè)字節(jié),并不會(huì)隨所指向變量的類型而改變。
-
雖然所有的指針都只占8個(gè)字節(jié),但不同類型的變量卻占不同的字節(jié)數(shù)。
一個(gè)int占用4個(gè)字節(jié),一個(gè)char占用1個(gè)字節(jié),而一個(gè)double占用8字節(jié);
現(xiàn)在只有一個(gè)地址,我怎么才能知道要從這個(gè)地址開始向后訪問多少個(gè)字節(jié)的存儲(chǔ)空間呢,是4個(gè),是1個(gè),還是8個(gè)。
所以指針變量需要它所指向的數(shù)據(jù)類型告訴它要訪問多少個(gè)字節(jié)存儲(chǔ)空間
也就是說,如果不指定指針的類型,那么當(dāng)指針指向一個(gè)變量的時(shí)候,她從首地址開始,但是它不知道什么時(shí)候停止,它不知道要訪問多少個(gè)存儲(chǔ)空間。比如有一個(gè)char類型的變量,我用一個(gè)指針指向它,但是這個(gè)指針我設(shè)置成int類型,這樣一來這個(gè)指針就會(huì)向后訪問四個(gè)字節(jié)的存儲(chǔ)空間,很明顯得到的結(jié)果不是char類型應(yīng)該得到的,所以要區(qū)分類型。