數組
定義:數組是有序的并且具有相同類型的資料的集合。
一維數組
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][]);是不允許的。