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

《Linux C一站式編程》第八章 數組

系統 1977 0

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

int count[4] = { 3, 2, };
數組和結構體雖然有很多相似之處,但也有一個顯著的不同:數組不能相互賦值或初始化。例如這樣是錯的:
int a[5] = { 4, 3, 2, 1 };
int b[5] = a;
既然不能相互賦值,也就 不能用數組類型作為函數的參數或返回值 。
void foo(int a[5])
{
...
}
int array[5] = { 0 };
foo(array);
編譯器也不會報錯,但這樣寫并不是傳一個數組類型參數的意思。對于數組類型有一條特殊規則: 數組類型做右值使用時,自動轉換成指向數組首元素的指針 。所以上面的函數調用其實是傳一個指針類型的參數,而不是數組類型的參數。這也解釋了為什么數組類型不能相互賦值或初始化,例如上面提到的 a = b 這個表達式, a b 都是數組類型的變量,但是 b 做右值使用,自動轉換成指針類型,而左邊仍然是數組類型,所以編譯器報的錯是 error: incompatible types in assignment 。
習題
1、編寫一個程序,定義兩個類型和長度都相同的數組,將其中一個數組的所有元素拷貝給另一個。既然數組不能直接賦值,想想應該怎么實現。
答:
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. 數組應用實例
調用C標準庫得到的隨機數其實是偽隨機(Pseudorandom)數,是用數學公式算出來的確定的數,只不過這些數看起來很隨機,并且從統計意義上也很接近均勻分布(Uniform Distribution)的隨機數。 C標準庫中生成偽隨機數的是 rand 函數,使用這個函數需要包含頭文件 stdlib.h ,它沒有參數,返回值是一個介于0和 RAND_MAX 之間的接近均勻分布的整數。 RAND_MAX 是該頭文件中定義的一個常量,在不同的平臺上有不同的取值,但可以肯定它是一個非常大的整數。
0~10的隨機數:int x = rand() % 11;

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

srand(time(NULL);

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

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

1.補完本節直方圖程序的 main 函數,以可視化的形式打印直方圖。
答:
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 { // 實際上只可能循環N次,因此外層while循環可改為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、定義一個數組,編程打印它的全排列。比如定義:
#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 個數中取 M 個數做組合而不是做排列,就不能用原來的遞歸過程了,想想組合的遞歸過程應該怎么描述,編程實現它。
答:

4. 字符串
字符串可以看作一個數組,它的每個元素是字符型的。
注意每個字符串末尾都有一個字符 '\0' 做結束符,這里的 \0 是ASCII碼的八進制表示,也就是ASCII碼為0的Null字符,在C語言中這種字符串也稱為以零結尾的字符串(Null-terminated String)。數組元素可以通過數組名加下標的方式訪問,而字符串字面值也可以像數組名一樣使用,可以加下標訪問其中的字符:
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 會從數組 str 的開頭一直打印到Null字符為止,Null字符本身是Non-printable字符,不打印。
如果數組 str 中沒有Null字符,那么 printf 函數就會訪問數組越界,后果可能會很詭異:有時候打印出亂碼,有時候看起來沒錯誤,有時候引起程序崩潰。
5. 多維數組
int a[3][2] = { 1, 2, 3, 4, 5 };

圖8.3.多維數組

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

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

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

圖8.4.多維字符數組


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

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

《Linux C一站式編程》第八章 數組


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产做受视频激情播放 | 操综合网| 猫咪www免费人成在线观看网址 | 在线亚洲免费 | 欧做爰xxxⅹ性欧美大片孕妇 | 亚洲精品麻豆 | 在线观看91精品国产不卡免费 | 天天插天天操天天干 | 欧美一区色 | 国产这里只有精品 | 一级一级 a爱片免费视频 | 亚洲一区 欧美 | 欧美精品一级毛片 | a一级毛片免费高清在线 | 国产在线精品福利大全 | 国产精品久久新婚兰兰 | 在线视频精品一区 | 四虎影视国产永久免费 | 久久99久久精品国产只有 | 一级毛片短视频 | 美女视频黄视大全视频免费网址 | 国产在线不卡视频 | 四虎在线看 | 国产精品模特hd在线 | 99久久这里只精品国产免费 | 久久精品资源 | 99热这里只有精品1 99热这里只有精品18 | 亚洲国产欧美国产综合一区 | 99国产福利 | 99久久综合| 久久激情影院 | 最近中文字幕精彩视频 | 久久亚洲影院 | 日本免费新一区二区三区 | 四虎地址| 黄毛片免费 | 久久人人爽人人爽人人片av不 | 国内精品自在自线在免费 | 国产精品播放 | 99热久久这里只有精品99 | 国产香蕉久久精品综合网 |