天天看點

c語言基礎學習05_數組和字元串

=============================================================================

涉及到的知識點有:for循環有兩種寫法、數組、一維數組定義與使用、一維數組的初始化、

如何得到一個一維數組的成員數量、查找出一維數組中成員最大值、查找一維數組的第二大元素的值、

一維數組的逆置、一維數組排序:冒泡排序、二維數組、二維數組的初始化、三維數組初始化、三維數組排序、

字元串與字元數組、字元數組的初始化、字元數組的使用(以及字元數組和字元串的差別)、去除輸出字元串結尾處的空格、

現在要去掉字元串最右面的空格,而不能去掉字元串中間的空格呢、随機數産生函數rand與srand、

自動的變種子、控制随機數的範圍、用scanf來輸入字元串、如何把兩次輸入的字元串放到新的字元串裡去、

scanf緩沖區溢出的危險的解釋、字元串的逆置。

for循環有兩種寫法:

第一種寫法:

int i;

for(i = 0; i < 10; i++)      //這個是标準C寫法,該寫法可以同時相容c和c++。

{

}

第二種寫法:

for(int i = 0; i < 10; i++)   //這個是C++寫法,該寫法有些編譯器不行,不支援。

差別:兩種寫法均可以,沒有對錯!

數組:就是在記憶體中連續的相同類型的變量空間。

1、一維數組定義與使用

例如:

int a[10];   //定義了一個一維數組,有10個成員,每個成員都是int類型,在記憶體中是連續存放的。

int a[10];   //從a[0]開始到a[9]結束,注意:沒有a[10]這個元素

a = 5;     //這句話是錯誤的。

      //數組的名字本身是一個常量,不能作為左值的。即不能把一個數組名當一個變量去用!!!

      //數組名:在c語言中數組名其實就是數組第一個元素的位址,是一個常量。

      (該常量是“變化”的,這裡面“變化”的意思是:隻要數組大小确定,首元素的位址随之确定)

      //即 a=&a[0]

-----------------------------------------------------------------------------

2、一維數組的初始化

各種各樣的寫法如下:

char a[5];           //等同于随機初始化,随機指派

char a[5] = {1,2,3,4};   //等同于定義後就初始化了

//預設後續元素為零的簡寫

char a[5] = {1,2};       //等同于char a[5] = {1,2,0,0};

//把所有成員的值都設為0的簡寫

char a[5] = {0};       //等同于char a[5] = {0,0,0,0};

int a[] = {1,2,3};      //等同于int a[3] = {1,2,3}

int a[] = {1,2,3,4,5,6};    //等同于int a[6] = {1,2,3,4,5,6};

3、如何得到一個一維數組的成員數量?

linux下的代碼如下:

1 #include <stdio.h>

2

3 int main()

4 {

5    int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,};//定義一個一維數組,每個成員都是int類型,在記憶體中是連續存放的。

6

7    int i;

8   for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)

9    {

10     printf("a[%d] = %d\n", i, a[i]);

11   }

12    //printf("%lu, %lu\n", sizeof(a), sizeof(a[0]));

13   return 0;

14 }

4、一個一維數組,其成員數量是随機的,數組成員的值也是随機的,需要查找出該數組中成員最大值。

4 {

5   int a[] = {-321, 52, 85, -78, 96, 789};

6      int i;

7   int tmp = a[0];

8   for (i = 1; i < sizeof(a) / sizeof(a[0]); i++)

9   {

10     if (a[i] > tmp)

11      tmp = a[i];

12    }

13   printf("max = %d\n", tmp);

14   return 0;

15 }

5、查找一維數組的第二大元素的值,要求隻能用一個循環,也不能用循環嵌套。

5    int a[] = {-321, 52, 85, -78, 96, 789};

7    //預設數組中第一個和第二個成員分别是最大的和第二大的

8    int max = a[0];

9    int smax = a[1];

10     if (a[0] > a[1])

11   {

12     max = a[0];

13     smax = a[1];

14   }

15   else

16  {

17     max = a[1];

18     smax = a[0];

19   }

20

21   int i;

22   for (i = 2; i < sizeof(a) / sizeof(a[0]); i++)

23  {

24      if (a[i] > max)

25      {

26          smax = max;

27        max = a [i];

28      }

29      else if (a[i] < max && a[i] > smax)

30      {

31        smax = a[i];

32      }

33     else

34     {

35     }

36   }

37

38   printf("smax = %d\n", smax);

39   return 0;

40 }

-----------------------------------------------------------------------------

6、一維數組的逆置

vs2017下的代碼如下:

#include <stdio.h>

int main()

  int a[] = { 45, 87, 56, 89, 52, 456, 489, 1235 };

  int min = 0; //代表數組的最小下标

  int max = 0; //代表數組的最大下标

  max = sizeof(a) / sizeof(a[0]) - 1;

  while (min < max)

  {

    int tmp = a[min];

    a[min] = a[max];

    a[max] = tmp;

    min++;

    max--;

  }

  //兩個元素交換的思路:要有一個臨時的量,把要交換的某一個量先存起來

  //int tmp = a[0];

  //a[0] = a[7];

  //a[7] = tmp;

  int i;

  for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)

    printf("a[%d] = %d\n", i, a[i]);

  return 0;

7、一維數組排序:冒泡排序

名詞解釋:将一個無序的一維數組排序成一個有序的一維數組,周遊這個一維數組,将最大的成員放到最後一個。

怎麼把最大的元素放到最後呢?思路是:兩個相鄰的元素依次比較,把大的放到小的後面。

例如:冒泡排序思路

第一次循環的時候:

12,45,73,55,81,36

12,45,55,73,81,36

12,45,55,73,36,81   這樣最大的元素跑到了最後

第二次再循環的時候:就不用管最後一個元素了

12,45,55,73,36

......

12,45,55,36,73       這樣第二大元素也跑到了最後

第三次再循環的時候:最後2個元素都不用管了

12,45,55,36,

12,45,36,55      這樣第三大元素也跑到了最後

依次類推......

再把思路轉換成代碼。。。。。。

  int a[] = { 32, 85, 98, 12, 56, 47, 654 , -789, 10 };

  int i, j;

  int max = sizeof(a) / sizeof(a[0]);

  for (i = 0; i < max; i++)

    for (j = 1; j < max - i; j++)

    {

      if (a[j - 1] > a[j]) //前面的元素大于後面的元素時,大的放在後面,從小到大,兩個元素交換

      {

        //int tmp = a[j - 1];

        //a[j - 1] = a[j];

        //a[j] = tmp;

        int tmp = a[j];

        a[j] = a[j - 1];

        a[j - 1] = tmp;

      }

    }

小注意事項:

int i = 10;

int a[i];   //這種定義數組的方法在過去的c标準中不能被支援,但C99以後的編譯器可以支援這種文法,一般最好不要這樣寫。

int a[10];       //但可以這樣寫

#define NUM 100   //也可以這樣寫

int a[NUM];

二維數組:本質一下子可以定義多個一維數組。

int a1[10];     //a1是一個一維數組,一維數組的數組名是a1。

int a2[2][10];   //a2是一個二維數組,二維數組的數組名是a2,這個二維數組中包含2個一維數組,分别是a2[0]、a2[1](注意a2[0]、a2[1]是一維數組的數組名),a2[0]和a2[1]這2個數組是連續的。

int a3[3][10];   //a3是一個二維數組,二維數組的數組名是a3,這個二維數組中包含3個一維數組,分别是a3[0]、a2[1]、a3[2](注意a3[0]、a3[1]、a3[2]是一維數組的數組名),a3[0]、a3[1]、a3[2]這3個數組是連續的。

再次複習:數組名:在c語言中數組名其實就是數組第一個元素的位址,是一個常量。常量是不可以做左值的。

對于下面而言:

int a2[2][10];

printf("%u, &u, %u\n", sizeof(a2), sizeof(a2[0]), sizeof(a2[0][0]));

printf("%p, %p, %p\n", a2, a2[0], &a2[0][0]);   //三個值是一樣一樣的!!!

-->sizeof(a2);           //80 a2是二維數組名,sizeof(a2);該句的意思是:二維數組的大小

* * * * * * * * * *

一維數組  -->sizeof(a2[0]);      //40 a2[0]是一維數組名,sizeof(a2[0]);該句的意思是:一維數組的大小

二維數組  -->sizeof(a2[0][0]);  //4 a2[0][0]是二維數組中的某一進制素(注意:也即一維數組的某一進制素哦!),sizeof(a2[0][0]);該句的意思是:二維數組中的某一進制素的大小(注意:也即一維數組的某一進制素的大小)

* - - - - - - - - -

- - - - - - - - - -

注意:是豎着排列的哦!!!

int a4[3][4][10];   //這是一個三維數組,有3個二維數組,二維數組名分别是:a4[0]、a4[1]、a4[2],每個二維數組中有4個一維數組,其中一個二維數組的一維數組的數組名分别是:a4[0][0]、a4[0][1]、a4[0][2]、a4[0][3]

三維數組:本質就是多個二維數組

- - - - - - - - - -   - - - - - - - - - -   - - - - - - - - - -    

- - - - - - - - - -   - - - - - - - - - -   - - - - - - - - - - 

- - - - - - - - - -   - - - - - - - - - -   - - - - - - - - - - 

三維數組初始化:要特别特别注意:二維數組有兩種輸出的排列方式:

例如對于int a5[2][3][4];

- - - -  - - - -    - - - -   -->橫着看,是一個二維數組,包含3個一維數組

- - - -  - - - -    - - - -      -->橫着看,是一個二維數組,包含3個一維數組

豎着看        豎着看

- - - -         - - - -

- - - -         - - - -

- - - -         - - - -

是一個二維數組      是一個二維數組

int a5[2][3][4] = { { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} },

       { {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24} } };

int a5[2][3][4] = { 0 };

周遊三維數組的核心代碼:(注意:列印的出來的橫着看的哦!!!)

int i, j, k;

for (i = 0; i < 2; i++)

  for (j = 0; j < 3; j++)

    for (k = 0; k < 4; k++)

      printf("a[%d][%d][%d] = %d,", i, j, k, a[i][j][k]);

    printf("\t");

  printf("\n");

二維數組的初始化

int a1[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };

int a2[3][4] = { {1, 2, 3, 4},{5, 6, 7, 8} };   //第三個數組預設置為0

int a3[3][4] = { 0 };   //将所有的成員都初始化為0

int a4[][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, { 8, 5, 9, 7}, {6, 8, 1, 2}};   //一維數組的個數不定

周遊二維數組的核心代碼:

for (i = 0; i < sizeof(a4) / sizeof(a4[0]); i++)

  for (j = 0; j < sizeof(a4[0]) / sizeof(a4[0][0]); j++ )

    printf("a4[%d][%d] = %d\t", i, j, a3[i][j]);

三維數組排序:把整個三維數組的所有成員進行排序

思路:(核心思想就是:降維或者稱之為:抽象為一維數組)

1、周遊三維數組後,把這個三維數組所有元素提出放到一個一維數組裡面,得到一個一維數組;

2、把這個得到的一維數組進行排序(使用冒泡排序);

3、把排序後的一維數組再放回到原來的三維數組裡;

4、為了看的見,再次周遊列印這個新的三維數組。

  int a[2][3][5] = { { {5,1,2,4,89}, {45,21,10,20,22}, {45,210,123,587,456}}, { {52,45,879,410,230}, {456,85,51,65,96}, {87,45,10,21,22}} };

  int b[30] = { 0 };

  int i, j, k;

  int index =0;

  //1、周遊三維數組後,把這個三維數組所有元素提出放到一個一維數組裡面,得到一個一維數組;

  for (i = 0; i < 2; i++)

    for (j = 0; j < 3; j++)

      for (k = 0; k < 5; k++)

        b[index] = a[i][j][k];

        index++;

  //2、把這個得到的一維數組進行排序(使用冒泡排序);

  for (i = 0; i < 30; i++)

    for (j = 1; j < 30 - i; j++)

      if (b[j - 1] > b[j])

        int tmp = b[j-1];

        b[j - 1] = b[j];

        b[j] = tmp;

  //3、把排序後的一維數組再放回到原來的三維數組裡;

  index = 0;

        a[i][j][k] = b[index];

  //4、為了看的見,再次周遊列印這個新的三維數組。

        printf("a[%d][%d][%d] = %d\n", i, j, k, a[i][j][k]);

字元串與字元數組

字元串定義: 字元串是記憶體中一段連續的char空間,以 '\0' 結尾。

字元數組定義: 字元數組也是記憶體中一段連續的char空間哦!(特别注意:字元數組并不)

是以在c語言中,字元串和字元數組有着千絲萬縷的聯系,特别相似,有時都是通用的哦!

舉例子如下:

char a[10];   //定義了一個字元類型的數組

a[0] = 'a';

a[1] = 'b';

a[2] = 'c';

a[3] = '\0';   //注意:0就是'\0'的ASCII碼哦!!!是以 a[3] = '\0'; 等價于 a[3] = 0;

printf("%s\n", a);    //輸出的是 abc

printf("%s\n", "abc");   //輸出的是 abc

說明了 char a[10];雖然是一個字元數組,但是它符合c語言中關于字元串的描述。

其實呢,c語言中并沒有單獨的字元串類型,字元串類型其實就是靠字元數組來表達的。

char a[10] = "aabbcc";//此為簡化的寫法。其實理應該一個個的指派那樣複雜的寫會更好的。初始化數組成員,注意:不能了解成定義的字元數組就等于右邊的字元串啊!!!

a = "hello";   //不能這樣寫,給數組名指派

字元數組的初始化

  初始化的時候,如果後面的值不寫的話,預設都是0。

  char a[10] ={ 'a', 'b', 'c'}; //複雜啰嗦的寫法,更直覺

  //a[0] = 'a';

  //a[1] = 'b';

  //a[2] = 'c';

  //a[3] = '\0'; //注意:0就是'\0'的ASCII碼哦!!!是以 a[3] = '\0'; 等價于 a[3] = 0;

  char a[10] = "abc"; //簡化寫法,更抽象,少寫一個是一個,哈哈哈!!!

  char a[] = "abc"; //注意這個字元數組有4個成員變量哦~

  //把一個字元數組所有成員都初始化為0(或叫初始化為空串),有以下兩種寫法哦~

  char a[10] = { 0 }; 或者 char a[10] = { '\0' };

  char a[10] = ""; //如果是空串,什麼都沒有,說明裡面隻有一個 '\0'(或0) 哦~

超級特别注意:0就是'\0'的ASCII碼,即他們倆是等價的,但是具體含義不一樣哦~

char a[12] = "hello world";

for (i =0; i < sizeof(a); i++)

  printf("%d\n", a[i]); //列印的結果為 104 101 108 108 111 32 119 111 114 108 100 0  注意:空格的ASCII是32,'\0'字元零的ASCII是0。

字元數組的使用(以及字元數組和字元串的差別)

在c語言中,沒有字元串這種資料類型,可以通過char的數組來替代,字元串就是以0結尾的char的數組。

如果有一個char的數組,但不是以'\0'(字元零或者0)結尾的,那麼這個數組就一定不是一個字元串,是以字元串是一種特殊的char的數組。

特别注意:(小心了解有偏差哦!!!)一個char的數組中可以出現多個字元零,但一個字元串中隻能有一個字元零。

是以說當我們用一個字元數組的時候,要明确的知道,該字元數組什麼時候可以當一個字元串用,什麼時候當一個數組使用。

  char a[7] = "hello";

  a[3] = '\0'; //等價于a[index] = 0;對于字元串來講,是"hel",對于字元數組來講,它的成員數量沒有變化,還是7個。

  //print("%s\n", a); //輸出的是:hel

  a[3] = 'l';

  a[5] = 'a';

  a[6] = 'a'; //這個時候a還是一個字元數組,但已經不是一個字元串了,因為結尾沒有以0結尾了,不符合c語言對字元串的定義和要求了。

  printf("%s\n", a); //輸出的是:helloaa燙燙滔窓

我的GitHub位址:

https://github.com/heizemingjun

我的部落格園位址:

http://www.cnblogs.com/chenmingjun

我的螞蟻筆記部落格位址:

http://blog.leanote.com/chenmingjun

Copyright ©2018 黑澤明軍

【轉載文章務必保留出處和署名,謝謝!】

繼續閱讀