亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

《Linux C一站式編程》第八章 數(shù)組

系統(tǒng) 2288 0

1. 數(shù)組的基本概念
數(shù)組(Array)也是一種復合數(shù)據(jù)類型,它由一系列相同類型的元素(Element)組成。
int count[4];
和結構體成員類似,數(shù)組 count 的4個元素的 存儲空間也是相鄰的 。結構體成員可以是基本數(shù)據(jù)類型,也可以是復合數(shù)據(jù)類型,數(shù)組中的元素也是如此。根據(jù)組合規(guī)則,我們可以定義一個由4個結構體元素組成的數(shù)組:
struct complex_struct {
double x, y;
} a[4];
struct {
double x, y;
int count[4];
} s;
使用數(shù)組下標不能超出數(shù)組的長度范圍,這一點在使用變量做數(shù)組下標時尤其要注意。C編譯器并不檢查 count[-1] 或是 count[100] 這樣的訪問越界錯誤,編譯時能順利通過,所以屬于運行時錯誤。但有時候這種錯誤很隱蔽,發(fā)生訪問越界時程序可能并不會立即崩潰,而執(zhí)行到后面某個正確的語句時卻有可能突然崩潰(在 第4節(jié) “段錯誤” 我們會看到這樣的例子)。
C語言的設計精神是:相信每個C程序員都是高手,不要阻止程序員去干他們需要干的事,高手們使用 count[-1] 這種技巧其實并不少見,不應該當作錯誤。)
數(shù)組也可以像結構體一樣初始化,未賦初值的元素也是用0來初始化,例如:

int count[4] = { 3, 2, };
數(shù)組和結構體雖然有很多相似之處,但也有一個顯著的不同:數(shù)組不能相互賦值或初始化。例如這樣是錯的:
int a[5] = { 4, 3, 2, 1 };
int b[5] = a;
既然不能相互賦值,也就 不能用數(shù)組類型作為函數(shù)的參數(shù)或返回值
void foo(int a[5])
{
...
}
int array[5] = { 0 };
foo(array);
編譯器也不會報錯,但這樣寫并不是傳一個數(shù)組類型參數(shù)的意思。對于數(shù)組類型有一條特殊規(guī)則: 數(shù)組類型做右值使用時,自動轉換成指向數(shù)組首元素的指針 。所以上面的函數(shù)調用其實是傳一個指針類型的參數(shù),而不是數(shù)組類型的參數(shù)。這也解釋了為什么數(shù)組類型不能相互賦值或初始化,例如上面提到的 a = b 這個表達式, a b 都是數(shù)組類型的變量,但是 b 做右值使用,自動轉換成指針類型,而左邊仍然是數(shù)組類型,所以編譯器報的錯是 error: incompatible types in assignment
習題
1、編寫一個程序,定義兩個類型和長度都相同的數(shù)組,將其中一個數(shù)組的所有元素拷貝給另一個。既然數(shù)組不能直接賦值,想想應該怎么實現(xiàn)。
答:
int main(void)
{
int array1[10] = { 3, 5, 1, 2, 2, 9, 1, 3, 4, 8 };
int array2[10];

int i;
for (i = 0; i < 10; i++) {
array2[i] = array1[i];
}

for (i = 0; i < 10; i++) {
printf("%d, ", array2[i]);
}
return 0;
}



2. 3. 數(shù)組應用實例
調用C標準庫得到的隨機數(shù)其實是偽隨機(Pseudorandom)數(shù),是用數(shù)學公式算出來的確定的數(shù),只不過這些數(shù)看起來很隨機,并且從統(tǒng)計意義上也很接近均勻分布(Uniform Distribution)的隨機數(shù)。 C標準庫中生成偽隨機數(shù)的是 rand 函數(shù),使用這個函數(shù)需要包含頭文件 stdlib.h ,它沒有參數(shù),返回值是一個介于0和 RAND_MAX 之間的接近均勻分布的整數(shù)。 RAND_MAX 是該頭文件中定義的一個常量,在不同的平臺上有不同的取值,但可以肯定它是一個非常大的整數(shù)。
0~10的隨機數(shù):int x = rand() % 11;

把上面的程序運行幾遍,你就會發(fā)現(xiàn)每次產生的隨機數(shù)都是一樣的,不僅如此,在別的計算機上運行該程序產生的隨機數(shù)很可能也是這樣的。這正說明了這些數(shù)是偽隨機數(shù),是用一套確定的公式基于某個初值算出來的,只要初值相同,隨后的整個數(shù)列就都相同。實際應用中不可能使用每次都一樣的隨機數(shù),例如開發(fā)一個麻將游戲,每次運行這個游戲摸到的牌不應該是一樣的。因此,C標準庫允許我們自己指定一個初值,然后在此基礎上生成偽隨機數(shù),這個初值稱為Seed,可以用 srand 函數(shù)指定Seed。通常我們通過別的途徑得到一個不確定的數(shù)作為Seed,例如調用 time 函數(shù)得到當前系統(tǒng)時間距1970年1月1日00:00:00的秒數(shù),然后傳給 srand

srand(time(NULL);

然后再調用 rand ,得到的隨機數(shù)就和剛才完全不同了。調用 time 函數(shù)需要包含頭文件 time.h ,這里的 NULL 表示空指針。

習題
1、用 rand 函數(shù)生成[10, 20]之間的隨機整數(shù),表達式應該怎么寫?
答:

1.補完本節(jié)直方圖程序的 main 函數(shù),以可視化的形式打印直方圖。
答:
int main(void)
{
gen_random(UPPER);

int i, histogram[UPPER] = {0};
for (i = 0; i < N; i++)
histogram[a[i]]++;

for (i = 0; i < UPPER; i++)
printf("%d\t", i);
printf("\n");
do { // 實際上只可能循環(huán)N次,因此外層while循環(huán)可改為for 0-> N-1,變量breakLoop也可以省了
int breakLoop = 1;
for (i = 0; i < UPPER; i++) {
if (histogram[i] > 0) {
printf("%c\t", '*');
histogram[i]--;
breakLoop = 0;
} else {

printf("\t");
}
}
printf("\n");
if (breakLoop)
break;
} while (1);

return 0;
}

2、定義一個數(shù)組,編程打印它的全排列。比如定義:
#define N 3
int a[N] = { 1, 2, 3 };

則運行結果是:
$ ./a.out
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2

最后再考慮第三個問題:如果要求從 N 個數(shù)中取 M 個數(shù)做組合而不是做排列,就不能用原來的遞歸過程了,想想組合的遞歸過程應該怎么描述,編程實現(xiàn)它。
答:

4. 字符串
字符串可以看作一個數(shù)組,它的每個元素是字符型的。
注意每個字符串末尾都有一個字符 '\0' 做結束符,這里的 \0 是ASCII碼的八進制表示,也就是ASCII碼為0的Null字符,在C語言中這種字符串也稱為以零結尾的字符串(Null-terminated String)。數(shù)組元素可以通過數(shù)組名加下標的方式訪問,而字符串字面值也可以像數(shù)組名一樣使用,可以加下標訪問其中的字符:
char c = "Hello, world.\n"[0];
編譯錯誤,字符串字面值是只讀的。
"Hello, world.\n"[0] = 'A';
char str[10] = "Hello";
相當于
char str[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };
最好讓編譯器自己計算:
char str[] = "Hello, world.\n";

printf("string: %s\n", str);

printf 會從數(shù)組 str 的開頭一直打印到Null字符為止,Null字符本身是Non-printable字符,不打印。
如果數(shù)組 str 中沒有Null字符,那么 printf 函數(shù)就會訪問數(shù)組越界,后果可能會很詭異:有時候打印出亂碼,有時候看起來沒錯誤,有時候引起程序崩潰。
5. 多維數(shù)組
int a[3][2] = { 1, 2, 3, 4, 5 };

圖8.3.多維數(shù)組

也可以:int a[][2] = { {1, 2} , {3, 4}, {5,} };
結構體數(shù)組
struct complex_struct {
double x, y;
} a[4] = { [0].x = 8.0; };

結構體元素是數(shù)組
struct {
double x, y;
int count[4];
} s = { .count[2] = 9 };

多維字符串數(shù)組
char days[8][10] = { "", "Monday", "Tuesday" ... "Sunday" };
printf("%s\n", days[day]);

圖8.4.多維字符數(shù)組


這個程序和 例4.1 “switch語句” 的功能其實是一樣的,但是代碼簡潔多了。簡潔的代碼不僅可讀性強,而且維護成本也低,像 例4.1 “switch語句” 那樣一堆 case printf break ,如果漏寫一個 break 就要出Bug。這個程序之所以簡潔,是因為用數(shù)據(jù)代替了代碼。具體來說, 通過下標訪問字符串組成的數(shù)組可以代替一堆 case 分支判斷,這樣就可以把每個 case 里重復的代碼( printf 調用)提取出來 ,從而又一次達到了“提取公因式”的效果。這種方法稱為數(shù)據(jù)驅動的編程(Data-driven Programming),寫代碼最重要的是選擇正確的數(shù)據(jù)結構來組織信息,設計控制流程和算法尚在其次,只要數(shù)據(jù)結構選擇得正確,其它代碼自然而然就變得容易理解和維護了,就像這里的 printf 自然而然就被提取出來了。

石頭剪刀布游戲問題:
留給讀者思考的問題是: (man - computer + 4) % 3 - 1 這個神奇的表達式是如何比較出0、1、2這三個數(shù)字在“剪刀石頭布”意義上的大小的?

《Linux C一站式編程》第八章 數(shù)組


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 99久久精品国产一区二区 | 欧美男女性生活视频 | 欧美一区二区三区精品影视 | 爽爽影院免费观看视频 | 国产成人亚洲综合小说区 | 国产在线干| 伊人久久网国产伊人 | 婷婷综合激情网 | 亚洲精品99久久久久中文字幕 | 亚洲一区国产 | 久久99久久精品97久久综合 | 九九香蕉视频 | 91系列在线| 免费观看国产网址你懂的 | 欧美中文字幕在线看 | 亚洲欧美另类国产 | 永久看日本大片免费 | 亚洲无总热门 | 亚洲欧美网站 | 青草99| 91视频这里只有精品 | 亚洲精品国产成人 | 六月色婷婷| 一二三区在线观看 | 最新毛片久热97免费精品视频 | 久久精品国产99久久3d动漫 | 女人洗澡一级毛片一级毛片 | 精品玖玖| 婷婷91| 国产精品爱久久久久久久9999 | 欧美精品香蕉在线观看网 | 乱人伦99久久 | 久热操 | 九九视频在线免费观看 | 麻豆国产在线观看一区二区 | 色综合天天综合网国产国产人 | 国产伦一区二区三区四区久久 | 成人毛片18女人毛片 | 九九亚洲精品自拍 | 26uuu亚洲| 久久久精品日本一区二区三区 |