1、數組的定義
類型符 數組名[常量表達式] int a[10]
數組下標實從0開始的,下標表示數組長度。
2、通過下標引用數組元素
數組名[下標]
下標可以是整型常量,也可以是整型表達式
3、引用數組元素。利用循環結構把數值0-9賦值給數組元素a[0]~a[9],然后按逆序輸出各元素的值
#include <stdio.h>
int main() { int i,a[10]; for(i=0;i<=9;i++) { a[i]=i; } for(i=9;i>=0;i--) { printf("%d",a[i]); } printf("\n"); return 0; }
4、一位數組的初始化
int a[5]={0,1,2,3,5}; // 定義長度為4的數組並初始化
int a[]={1,2,3,4,5}; // 長度根據后面元素個數自行定義
int a[10]={0,1,2,3}; // 長度多於實際元素個數,后面補0
5、用數組處理斐波那契數列問題,輸出數列中前20個數。
#include <stdio.h>
int main() { int i; int f[20]={1,1}; // 第一、第二項
for(i=2;i<20;i++) // 求出f[2]到f[19]的值,這里i只是下標變量
{ f[i]=f[i-2]+f[i-1]; // 第三項是第一項與第二項的和
} for(i=0;i<20;i++) // 遍歷數組
{ if(i%5==0) // 每5個元素打印一行
{ printf("\n"); } printf("%12d",f[i]); } printf("\n"); return 0; }
對比之前循環章節來分析,數組可以按需輸出第幾個元素。
6、冒泡排序:假如有n個人,各人年齡不同,希望按年齡將他們從小到大排列
#include <stdio.h>
int main() { int a[10]; int i,j,t; printf("Please enter 10 numbers :\n"); for(i=0;i<10;i++) // 要輸入多個數
{ scanf("%d",&a[i]); } for(j=0;j<9;j++) // j是由多少趟:排列數字個數-1 { for(i=0;i<9-j;i++) // 每一趟中要比較多少次 9-j { if(a[i]>a[i+1]) { t=a[i]; a[i]=a[i+1]; a[i+1]=t; } } } printf("The sorted numbers:\n"); for(i=0;i<10;i++) { printf("%2d\t",a[i]); } printf("\n"); return 0; }
7、二維數組
(1)定義一個二維數組
類型名 數組名[常量表達式][常量表達式] float a[3][4],b[5][10]; // a為3×4列的數組
(2)引用二維數組
a[1][2]=b[1][2]/2 //數組元素可以出現在表達式中,也可以被賦值
(3)二維數組的初始化
1)分行賦初值
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2)按數組排列賦值
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
3)部分賦值
int a[3][4]={{1},{5},{9}} // 只對各行的第一個元素賦值
int a[3][4]={{1},{0,6},{0,0,11}}; // 沒有賦值的自動補零
int a[3][4]={{1},{},{9}}; // 第二行不賦值
4)一維的下標可以省略,但是二維不能省略
int a[][4]={{0,0,3},{},{0,10}};
8、將一個二維數組a的行和列的元素互換(即行列轉置),存到另一個二維數組b中。
#include <stdio.h>
int main() { int i,j; int a[2][3]={{1,2,3},{5,6,7}}; // 定義數組a並賦值
int b[3][2]; // 定義數組b長度,不賦值
printf("array a:\n"); for(i=0;i<2;i++) // i控制行數的變化
{ for(j=0;j<3;j++) // j控制列數的變化
{ printf("%3d",a[i][j]); // 輸出a數組中i行j列元素
b[j][i]=a[i][j]; // 將a數組i行j列元素,賦值給b數組j行i列元素 } printf("\n"); } printf("array b:\n"); for(i=0;i<3;i++) // 遍歷輸出b數組的值
{ for(j=0;j<2;j++) { printf("%5d",b[i][j]); // 此處的i,j表示的是b數組的幾行幾列 即 j=i } printf("\n"); } return 0; }
9、有一個班5個學生,已知每個學生有5門成績,要求輸出平均成績最高的學生的成績以及該學生的序號
#include <stdio.h>
int main() { int i,j,sum,num=5; // i為行數,j為列數,sum為每行的總分
int max=0,max_i; // 假設該行最大max為0,max_i用於存儲最大平均成績的下標
int average[5]; // average數組用於存放每個(行)學生的平均成績
float score[5][5]={{71,81,91,80,70},{72,82,92,80,70},{90,90,90,90,90},{62,82,78,90,81},{82,71,81,78,67}}; for(i=0;i<5;i++) { sum=0; // 計算每一個科成績的時候,sum都從零開始 for(j=0;j<5;j++) { sum=sum+score[i][j]; } printf("第%d個學生的總分:%10d\n",i,sum); average[i]=sum/num; printf("第%d個學生的平均分:%8d\n",i,average[i]); printf("\n"); } for(i=0;i<5;i++) { if(average[i]>max) { max=average[i];max_i=i; } } printf("_____________________________\n"); printf("第%d個的學生的平均成績最高:%d\n\n",max_i,max); return 0; }
10、字符數組
(1)定義字符數組並初始化
char c[5];
c[0]='C';c[1]='h';c[2]='i';c[3]='n';c[4]='a';
char c[5]={'C','h','i','n','a'};
PS:字符數組和普通數組也可以根據實際元素個數自行按需定義長度
(2)引用字符數組
#include <stdio.h>
int main() { int i,j; char diamond[5][5]={{' ',' ','*',' ',' '},{' ','*',' ','*',' '},{'*',' ',' ',' ','*'},{' ','*',' ','*',' '},{' ',' ','*',' ',' '}}; for(i=0;i<5;i++) // 控制行 { for(j=0;j<5;j++) // 控制列 { printf("%c",diamond[i][j]); } printf("\n"); } return 0; }
PS:C語言中,將字符串作為字符數組來處理,如果字符數組的定義的長度,而實際元素沒有這么多,編譯系統會自動加一個"\0" 作為 結束符 。
(3)用字符串常量來初始化數組
char c[]="I am happy"; // 用字符常量初始字符數組,后面自動補'\0',這里數組長度為11. char b[]={'I',' ','a','m',' ','h','a','p','p','y'}; // 單個字符賦值為數組,數組長度為10
(4)字符數組的格式輸入輸出
1)逐個輸入輸出。格式聲明用 "%c"
2)整個字符串一次輸入輸出。格式聲明用 "%s"。
char c[]="I am happy"; printf("%s\n",c); // 這樣就不用for循環逐個遍歷打印啦!
3)注意的幾點:
① 輸出字符不包括結束符"\0";
② 不管字符數組多長,遇到"\0"就結束,不管結束符有多少個,遇到第一個就結束;
③ 未賦值元素自動補"\0";
④ 如果scanf函數的輸入項是字符數組名,則不用加地址符"&",因為數組名就代表起始地址,用printf函數輸出也同理;
(5)字符串處理函數
gets(輸入)、puts(輸出)、strcat(拼接)、strcpy(復制)、strcmp(比較)、strlen(長度)、strlwr(大轉小)、strupr(小轉大)
11、字符數組應用舉例
1)有3個字符串,要求找出其中“最大”者
#include <stdio.h>
#include <string.h> int main() { char string[20]; // 存放“最大”字符串 char str[3][20]; int i;
for(i=0;i<3;i++) { gets(str[i]); // 讀入三個字符串,並存放在字符數組str中 } if(strcmp(str[0],str[1])>0) // 比較串0和串1 { strcpy(string,str[0]); // 如果串0比串1大,則存放串0在string中 }else { strcpy(string,str[1]); // 否則存放串1 } if(strcmp(str[2],string)>0) // 再拿串3和string的字符串比較 { strcpy(string,str[2]); // 如果比里面的大,則覆蓋 } printf("The largest string is:\n%s\n",string);
return 0; }
2)輸入一行字符,統計其中有多少個單詞,單詞之間用空格分隔開
#include <stdio.h> #include <string.h>
int main() { char string[81]; int i,num=0,word=0; // 開始時,單詞數為0,未出現單詞
char c; // c用來存放當前需要判斷的字符
gets(string); // 讀入一個字符串,存放在string數組中
for(i=0;(c=string[i])!='\0';i++) // 從第一個字符串,到最后一個字符串
{ if(c==' ') // 如果當前字符是空格,則使word置0
{ word=0; }else if(word==0) // 若當前字符不是空格,而且前一個字符是空格
{ word=1; // 使word置1
num++; // 使num加1
} } printf("There are %d words in the line.\n",num); return 0; }
提高部分
1、gets函數(讀入字符串函數)
char str[20]; gets(str); // 從鍵盤輸入一個字符串,存放在str數組中
2、pust函數(輸出字符串函數)
char str[]={"happy!"}; puts(str); // 輸出str字符串在屏幕,實際和printf差不多
3、strcat(字符串連接函數)
char str1[30]={"People's of Republic"}; char str2[]={"China"}; printf("%s",strcat(str1,str2)); // 將字符串2拼接到字符串1
4、strcpy和(整個字符串)
strcpy(字符數組,字符串2) char str1[10]='',str2[]={"China"}; strcpy(str1,str2); // 將字符串2復制給字符串1
5、strncpy(復制前幾個字符)
strncpy(str1,str2,2);
6、strcmpy函數(字符串比較函數)
strcpy(字符串1,字符串2)
- 如果字符串1=字符串2,則函數值為0
- 如果字符串1>字符串2,則函數值為一個正整數
- 如果字符串1<字符串2,則函數值為負整數
if(strcmp(str1,str2)>0) printf("yes");
7、strlen函數(測字符串長度函數)
char str[10]={"China"}; printf("%d",strlen(str));
8、strlwr函數(轉換為小寫) lwr
9、strupr函數(轉換為大寫) upr
習題部分
1、一個班有10個學生的成績,要求輸入這10個學生的成績,然后求出他們的平均分。
#include <stdio.h>
int main() { int a[10]; int i,sum=0,average; printf("Please enter student's scores:\n"); for(i=0;i<10;i++) { scanf("%d",&a[i]); sum+=a[i]; } average=sum/10; printf("The average score is %d\n",average); return 0; }
2、在上題基礎上求出平均成績最高的課程(以課程序號表示)及其成績
#include <stdio.h>
int main() { int a[3][5]; // 存放學生成績,行為科目,列學生
int average[3]; // 用來存放每科的平均成績
int i,j,max,max_s; printf("Please enter student's scores:\n"); for(j=0;j<3;j++) // 控制行
{ int sum=0; // 每次單科成績總分都是從0算起的
for(i=0;i<5;i++) // 控制列
{ scanf("%d",&a[j][i]); sum=sum+a[j][i]; // 也就是按行加
} average[j]=sum/5; // 一行統計完之后計算該行平均成績,並賦值給average數組
printf("The average score is %d\n",average[j]); } printf("_________________\n"); for(j=0;j<3;j++) // 遍歷平均分數組進行比較
{ if(average[j]>average[j+1]) { max=average[j];
max_s=j; // 如果該行最大,則返回行數(課程序號)
}else { max=average[j+1]; } } printf("最大平均分為:%d\n該課程的序號為:%d\n",max,max_s); return 0; } // 此程序有bug哈哈哈哈
3、已知一個班10個學生的成績,存放在一個一維數組中,要求找其中成績最高的學生的成績和該學生的序號
#include <stdio.h>
int main() { int score[10]={70,80,60,60,70,90,80,100,90,80}; // 存放10個學生的成績
int j,max=0,max_p; // 假設最大值是 0
for(j=0;j<10;j++) { if(score[j]>max) { max_p=j+1; max=score[j]; } } printf("最大平均分為:%d\n該課程的序號為:%d\n",max,max_p); return 0; }
4、有3個學生,上4門課,要求輸入全部學生的各課成績,並分別求出每門的平均成績
#include <stdio.h>
int main() { int score[3][4]; int average[3]; int i,j; printf("請輸入第1門課程學生的成績:\n"); for(i=0;i<3;i++) { int sum=0; for(j=0;j<4;j++) { scanf("%d",&score[i][j]); sum+=score[i][j]; } average[i]=sum/4; printf("請輸入第%d門課程學生的成績:\n",i+2); } printf("________________________________\n"); for(i=0;i<3;i++) { printf("第%d門課程的平均分為:%d\n",i+1,average[i]); } return 0; }
5、已知5個學生的4門課成績,要求求每個學生的平均成績,然后對平均成績從高到低將個學生的成績記錄排序(成績最高的學生排在數組最前面的行,成績最低的學生排在數組最后面的行)。
/* 答案不正確的哇*/ #include <stdio.h> int main() { int score[5][4]={{60,60,70,70},{80,80,85,70},{80,90,90,90},{60,60,70,60},{80,80,80,90}}; int average[5]; int i,j,sum,temp; for(i=0;i<5;i++) { sum=0; for(j=0;j<4;j++) { printf("%d\t",score[i][j]); sum+=score[i][j]; // printf("%d",sum); } average[i]=sum/4; printf("average:%d",average[i]); printf("\n"); } // i-1; for(i=0;i<4;i++) { for(j=0;j<4-i;j++) { if(average[j]<average[j+1]) { temp=average[j]; average[j]=average[j+1]; average[j+1]=temp; } } } printf("\n"); for(i=0;i<5;i++) { printf("%d\t",average[i]); } printf("\n"); return 0; }
6、將一個數組中的值按照逆序重新存放。
1)用兩個數組實現
#include <stdio.h>
int main() { int i; int t[5]; int a[5]={43,54,65,74,87}; for(i=0;i<5;i++) { t[i]=a[4-i]; a[i]=t[i]; printf("%d\t",a[i]); } return 0; }
2)用一個臨時變量實現
#include <stdio.h>
#define N 5
int main() { int a[N],i,temp; printf("enter array a:\n"); for (i=0;i<N;i++) scanf("%d",&a[i]); printf("array a:\n"); for (i=0;i<N;i++) printf("%4d",a[i]); for (i=0;i<N/2;i++) //循環的作用是將對稱的元素的值互換
{ temp=a[i]; // 每次循環將a[i]的值存儲起來 a[i]=a[N-i-1]; // a[i]的位置對着數組倒數的元素,關系是假設有5個元素,則a[0]---a[4],a[1]---a[3] a[N-i-1]=temp; // 后面的位置代回存儲在temp的a[i] } printf("\nNow,array a:\n"); for (i=0;i<N;i++) printf("%4d",a[i]); printf("\n");
7、打印下面圖案
*****
*****
*****
*****
*****
#include <stdio.h> int main() { int i,j; char c[]={"*"}; for(i=0;i<5;i++) { for(j=0;j<i+1;j++) { printf(" "); } for(j=0;j<5;j++) { printf("%s",c); } printf("\n"); } return 0; }
8、有一篇短文,共有3行文字,每行有80個字符。想統計其中英文大寫字母,小寫字母,數字、空格及其他字符各有多少個。
#include <stdio.h> int main() { int i,j; int E=0,e=0,n=0,s=0,o=0; char a[3][80]={ {"Mr.Johnson had never been up in an aerophane before and he had read a lot about"}, {" air accidents, so one day when a friend offered to take him for a ride in his "}, {"won small phane, Mr. Johnson was very worried about accepting. Finally, 1234 56"}}; for(i=0;i<3;i++) { for(j=0;j<80;j++) { printf("%c",a[i][j]); if(a[i][j]>64&&a[i][j]<91) { E++; } else if(a[i][j]>96&&a[i][j]<123) { e++; } else if(a[i][j]>47&&a[i][j]<58) { n++; }else if(a[i][j]==' ') { s++; }else if(a[i][j]!='\0') // 其他情況就是不是數組結尾時,統計其他字符個數 { o++; } } printf("\n"); } printf("\n"); printf("大寫個數:%5d\n小寫個數:%5d\n數字個數:%5d\n空格個數:%5d\n其他個數:%5d\n",E,e,n,s,o); return 0; }
9、有一行電文,已按照下面的規律譯成密碼,要求求密碼原文
A—>Z a—>z
B—>Y b—>y
C—>X c—>x
... ...
#include <stdio.h>
int main() { char str[20]; gets(str); printf("Key: "); puts(str); int i; for(i=0;i<=20;i++) { if(str[i]>='A' && str[i]<='Z') str[i]=65+90-str[i]; if(str[i]>='a' && str[i]<='z') str[i]=97+122-str[i]; } printf("Text: "); puts(str); return 0; }
#include<stdio.h> #include <string.h>
int main() { char s[1024] = {0}; scanf("%s", s); int len = strlen(s) // 轉換
for (int i = 0; i < len; ++i) { // 如果是小寫字母(大寫字母出來類似): // 1. 先用s[i] - 'a'計算出s[i]是26個字母中從前往后數的第幾個 // 2. 再用26 - (s[i]- 'a') - 1 轉換為26個字母中從后往前數的第幾個 // 3. 在2的結果上加上'a',即轉換為對應從后往前的第幾個字母 if (s[i] >= 'a' && s[i] <= 'z') s[i] = 'a' + 26 - (s[i]-'a')-1; else if (s[i] >= 'A' && s[i] <= 'Z') s[i] = 'A' + 26 - (s[i] - 'A')-1; } printf("%s\n", s); return 0; }
10、編寫一個程序,將了兩個字符串連接起來,(1)用strrcat函數,(2)不用strcat函數
(1)用strrcat函數
#include<stdio.h> #include <string.h>
int main() { char a[20]={"Hello "}; char b[]={"World!"}; printf("%s\n",strcat(a,b)); return 0; }
(2)不用strcat函數
#include<stdio.h> #include <string.h>
int main() { int i,len_a,len_b; char a[20]={"Hello "}; char b[]={"World!"}; len_a=strlen(a); len_b=strlen(b); for(i=0;i<len_b;i++) { a[len_a+i]=b[i]; } puts(a); printf("%d,%d\n",len_a,len_b); return 0; }