天天看點

數組結構體總結(C語言)

數組

定義:數組是有序的并且具有相同類型的資料的集合。

一維數組

1、一般形式:類型說明符 數組名[常量表達式];例如: int a[10]; 元素為a[0]----a[9].

2、常量表達式中不允許包含變量,可以包含常量或符号常量。

3、數組元素下标可以是任何整型常量、整型變量或任何整型表達式。

4、可以對數組元素指派,數組元素也可以參與運算,與簡單變量一樣使用。

5、使用數值型數組時,不可以一次引用整個數組,隻能逐個引用元素。

6、需要整體指派時隻可以在定義的同時整體指派。如

   int a[10]={0,1,2,3,4,5,6,7,8,9};正确。

   int a[10];    a[10]={0,1,2,3,4,5,6,7,8,9};錯誤。

或者用記憶體拷貝函數

7、可以隻給一部分元素指派。例如:

   int a[10]={5,8,7,6};後面沒有指派的元素值預設為0。

8、對全部數組元素指派時可以不指定數組長度,例如:

   int a[10]={0,1,2,3,4,5,6,7,8,9};可以寫成 int a[]={0,1,2,3,4,5,6,7,8,9};

   但是,既不賦初值,也不指定長度是錯誤的。例如:int a[];錯誤。

9、指向數組元素的指針

     int a[10], *p; 

//下面這兩句是等價的:

     p=&a[0]; 

     p=a; 

根據位址運算規則, a+1為a[1]的位址, a+i就為a[i]的位址。 

    下面我們用指針給出數組元素的位址和内容的幾種表示形式。 

    (1). p+i和a+i均表示a[i]的位址, 或者講, 它們均指向數組第i号元素, 即 

指向a[i]。 

    (2). *(p+i)和*(a+i)都表示p+i和a+i所指對象的内容, 即為a[i]。 

    (3). 指向數組元素的指針, 也可以表示成數組的形式, 也就是說,  它允許 

指針變量帶下标, 如p[i]與*(p+i)等價。 

二維數組

1、一般形式:類型說明符 數組名[常量表達式1][常量表達式2];例如: 

   int a[3][4];可以看成是包含3個一維數組,每個一維數組裡包含4個元素。一共3*4=12個元素。 

   所有元素為 a[0][0],a[0][1],a[0][2],a[0][3]

              a[1][0],a[1][1],a[1][2],a[1][3]

              a[2][0],a[2][1],a[2][2],a[2][3]

         ┏━━━━┓    ┏━┳━┳━┳━┓ 

 a─→┃  a[0]    ┃─→┃0 ┃1 ┃2 ┃3 ┃ 

         ┣━━━━┫    ┣━╋━╋━╋━┫ 

         ┃  a[1]    ┃─→┃4 ┃5 ┃6 ┃7 ┃ 

         ┣━━━━┫    ┣━╋━╋━╋━┫ 

         ┃  a[2]    ┃─→┃8 ┃9 ┃10┃11┃ 

         ┗━━━━┛    ┗━┻━┻━┻━┛

a代表二維數組的首位址,  當然也可看成是二維 數組第0行的首位址。a+1就代表第1行的首位址, a+2就代表第2行的首位址。如 果此二維數組的首位址為1000, 由于第0行有4個整型元素, 是以a+1為1008, a+2 

也就為1016(16位)。如下圖所示 

                            a[3][4] 

                     a    ┏━┳━┳━┳━┓ 

              (1000)─→┃0 ┃1 ┃2 ┃3 ┃ 

                    a+1  ┣━╋━╋━╋━┫ 

              (1008)─→┃4 ┃5 ┃6 ┃7 ┃ 

                    a+2  ┣━╋━╋━╋━┫ 

              (1016)─→┃8 ┃9 ┃10┃11┃ 

                           ┗━┻━┻━┻━┛ 

2、與一維數組一樣元素下标可以是是任何整型常量、整型變量或任何整型表達式。

3、需要整體指派時隻可以在定義的同時整體指派。例如:

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

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

4、可以把所有資料寫在一個花括号内。例如:

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

5、可以隻對部分元素指派。例如:

   int a[3][4]={{1},{5},{9}};其餘未指派的元素預設為0。

   int a[3][4]={{1},{5,6}};可以看成是int a[3][4]={{1,0,0,0},{5,6,0,0},{0,0,0,0}};

6、對全部數組元素指派時可以省略第一維長度,第二維不可以省略。例如:

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

   可以寫成a[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

   或者a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};

7、在二維數組中, 我們還可用指針的形式來表示各元素的位址。

a[0]與*(a+0)等價, a[1]與*(a+1)等價, 是以a[i]+j就與*(a+i)+j等價, 它 

表示數組元素a[i][j]的位址。 

是以, 二維數組元素a[i][j]可表示成*(a[i]+j)或*(*(a+i)+j),  它們都與 

a[i][j]等價, 或者還可寫成(*(a+i))[j]。

字元數組

1、定義:char a[10];字元數組a長度為10。每個元素隻能存放一個字元。例如:

   a[0]='h';a[1]='a';a[2]='p';……

2、初始化:

   char a[]={'h','a','p','p','y'};注意,長度為5

   char a[]="happy";

   char a[]={"happy"}; 注意,因為字元串結尾自動加'\0',是以char a[]="happy";長度為6,不是5。

3、C語言中沒有字元串變量,字元串的輸入、存儲、處理和輸出等必須通過字元數組實作。  隻能是數組指針都不行!

4、字元串的輸入。

   scanf();可以用%C逐個字元輸入比如char a[6];for(i=0;i<6;i++) scanf("%c",&a[i]);

           可以用%S以字元串的形式輸入,比如char a[6];scanf("%s",a);注意,a前不用加&,因為a是數組名,已經代表了數組首位址。

           注意:以%S輸入時,以第一個非空白字元開始,終止于第一個空白字元。比如:輸入How are you時。隻輸出How.

   gets();作用為輸入一個字元串。與scanf();功能一緻,但空格和回車都存放在數組中,最後自動加入‘\0’.不會出現上面輸出不全的情況。

         調用方式為:gets(數組名);需要包含頭檔案“stdio.h”.

5、字元串的輸出。

    printf();可以使用%C逐個字元輸出,比如:char a[6];for(i=0;i<6;i++) printf("%c",a[i]);

           可以用%S以字元串的形式輸出,比如char a[6];printf("%s",a);

    puts();輸出一個字元串,結尾自動換行。

         調用形式:puts(字元數組名或字元串常量);需包含頭檔案“stdio.h”

常用字元串處理函數(以下函數需要頭檔案“string.h”)

1、strlen()作用是測試字元串長度。這裡不包括‘\0’.使用形式strlen(數組名或字元串常量)

2、strcat()作用是連接配接兩個字元串。調用方式strcat(字元數組1名,字元數組2名);合并後的字元串存放在字元數組1中。

3、strcmp()比較兩個字元串是否相等。調用方式strcmp(字元串1,字元串2);相等時值為0。1>2時為正數。1<2時為負數。

4、strcpy()複制字元串。調用方式strcpy(字元數組1,字元串2);2的内容複制到1中。1隻能是字元數組名。

指針數組

1、定義int *p[10];//指針數組,含有10個指針元素

也就是說每一個元素都是指針

2、初始化:

char *week_day[8]= 

{"sunday", 

"monday", 

"tuesday",

"wednesday", 

"thursday", 

"friday", 

"saturday", 

NULL 

};  

char *week_day[8];

數組必須指定大小,char *week_day[];是錯誤的。

可以不指定數組大小

char * week_day []=

{"sunday", 

"monday", 

"tuesday",

"wednesday", 

"thursday", 

"friday", 

"saturday", 

NULL 

};

3、使用

int *p[10];

p[0]=”asdfghj”;

char *a=”asdfghjk”; 

p[1]=a;

4、指向結構體的指針數組

 typedef struct { 

char s1[81]; 

char s2[81]; 

char s3[81]; 

} Rec; 

Rec *a[10];

a[0]=(Rec *)malloc(sizeof(Rec)); 

strcpy(a[0]->s1, "hello"); 

free(a[0]);

如右圖所示:

5、指向函數的指針數組

      int functionA(int event);

        int functionB(int event);

     …….

    int functionZ(int event);

  typdef  int (*pFunc)(int event);   // pFunc 是 int (*)(int event)的别名

  pFunc  functionlist[Z+1] =

functionA,

 functionB, 

…  ,

functionZ 

}; //指向函數名串的指針數組 

  使用:

functionlist[i](event);

數組指針

1、定義:

類型說明符  (*指針變量名)[長度]

注意“(*指針變量名)”兩邊的括号不可少。

int (*p)[10];//數組指針,這個指針能夠用來指向含有10個元素的整數數組

2、使用

int a[10], b[3][4],

p = &a;  注意,取一次位址位址相當于加一級指針

p=b;

*p+1指向b[0][1], *(p+i)+j則指向數組元素b[i][j]。

結構體數組

1、 結構體數組的定義

   對應結構體變量定義方法1

struct student

{

 long num;

   char name[20];

char sex;

   char addr[20];

};

struct student students[3];

struct 

{

 long num;

   char name[20];

char sex;

   char addr[20];

} students[3];

2、結構體數組的初始化

   初始化方法: 在定義數組的後面加上  ={初值清單}

如: 

struct 

{  long num;

         char name[20];

         char sex;

         char addr[20];

}   students[3]={ {10101, "Li Lin", 'M', "Beijing"},{10102, "zhang",  'F',  "shanghai"} …...};

3、使用

students [i].sex=‘F’;

數組作為函數參數

1、 數組元素作函數實參

數組元素作函數實參,與用變量作實參一樣,是“單向的值傳遞”。

參數和形參類型要保持一緻。

Fun(a[2]);//傳遞的是元素a[2]的值。

2、 數組名作函數的實參和形參。

如:

main()

{int array[10];

   ……

 f(array,10);

……

}

 f(int arr[],int n);

     {    ……

}//注意sizeof(arr)值為4,此處隻是傳遞數組的第一個元素的位址。

array為實參數組名,arr為形參數組名。數組名就是數組的首位址,實參向形參傳送數組名實際上就是傳送數組的位址,形參得到該位址後也指向同一數組。這就好象同一件物品有兩個彼此不同的名稱一樣。

    同樣,指針變量的值也是位址,數組指針變量的值即為數組的首位址,也可作為函數的參數使用。

用數組名作為函數參數時還應注意以下幾點:

a. 形參數組和實參數組的類型必須一緻,否則将引起錯誤。

b. 形參數組和實參數組的長度可以不相同,因為在調用時,隻傳送首位址而不檢查形參數組的長度。當形參數組的長度與實參數組不一緻時,雖不至于出現文法錯誤(編譯能通過),但程式執行結果将與實際不符,這是應予以注意的。

c. 在函數形參表中,允許不給出形參數組的長度,或用一個變量來表示數組元素的個數。

例如,可以寫為:

void fun(int a[])

或寫為

void fun(int a[],int n)

其中形參數組a沒有給出長度,而由n值動态地表示數組的長度。n的值由主調函數的實參進行傳送。

d. 多元數組也可以作為函數的參數。在函數定義時對形參數組可以指定每一維的長度,也可省去第一維的長度。是以,以下寫法都是合法的。

      int MA(int a[3][10])

int MA(int a[][10])。

而int  MA (int a[3][]);是不允許的。

繼續閱讀