Presentation is loading. Please wait.

Presentation is loading. Please wait.

C程序设计.

Similar presentations


Presentation on theme: "C程序设计."— Presentation transcript:

1 C程序设计

2 第7章 数组 前几章使用的都是属于基本类型(整型、字符型、实型)的数据,C语言还提供了构造类型的数据,它们有数组类型、结构体类型和共用体类型。构造类型数据是由基本类型数据按一定规则组成的,因此它们又被称为“导出类型”。 数组是有序数据的集合。数组中的每一个元素都属于同一个数据类型。用一个统一的数组名和下标来惟一地确定数组中的元素。 /*int grade[10]; for(int i=0; i<=9; i++) scanf("%d", &grade[i]); for(int j=0; j<=9; j++) printf("%d ", grade[j]);*/ 为什么需要使用数组? 1、解决同类型数据的存储和使用问题; 2、 为了模拟显示世界;

3 7.1 一维数组的定义和引用 7.1.1 一维数组的定义 一维数组的定义方式为 类型说明符 数组名[常量表达式];
例如:int a[10]; 说明: (1)数组名的命名规则和变量名相同,遵循标识符命名规则。 (2)在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。 (3)常量表达式中可以包括常量和符号常量,不能包含变量。C语言不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。

4 7.1.2 一维数组元素的引用 数组必须先定义,然后使用。C语言规定只能逐个引用数组元素而不能一次引用整个数组。 数组元素的表示形式为
数组名[下标] 下标可以是整型常量或整型表达式。 一维数组 为n个变量连续分配存储空间; 所有的变量数据类型必须相同; 所有变量所占的字节大小必须相同; 不能用变量来初始化数组长度; scanf("%d", &l); int a[l]; //错误的,用变量初始化数组长度 例如: int a[5]; 一维数组名不代表数组中所有的元素,一维数组名代表数组第一个元素的地址,是个指针常量。 /*int a[10]; for(int i=0; i<=9; i++) a[i]=i; //printf(“%x\n”, a); //代表的是第一个元素的首地址 //printf("%x\n", &a[0]); //printf(“%x\n”, &a[1]); //数组是一组在空间上连续的变量集合

5 [例7.1]数组元素的引用 #include <stdio.h> void 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”); }

6 7.1.3 一维数组的初始化 对数组元素的初始化可以用以下方式实现 (1)在定义数组时对数组元素赋予初值。 (2)可以只给一部分元素赋值。
(3)如果想使一个数组中全部元素值为0,可以写成: int a[2]={0,0}或int a[2]={0};。 (4)在对全部数组元素赋初值时,由于数据的个数已经确定,因此可以不指定数组长度。 初始化 完全初始化 int a[5]={1,2,3,4,5}; for (int i=0; i<=4; i++) printf("a[%d]=%d\n", i, a[i]); 不完全初始化,未被初始化的元素自动为零 int a[5]={1,2,3}; 不初始化,所有元素都是垃圾值 int a[5]; 清零 int a[5]={0}; 错误写法: int a[5]; a[5]={1,2,3,4,5}; .//错误,只有在定义数组的同时才可以赋值,其他情况下整体赋值都是错误的; int a[5]={1,2,3,4,5} a[5]=100; //错误,因为没有a[5]这个元素,最大只有a[4] int a[5]={1,2,3,4,5}; int b[5]; 如果要把a数组中的值全部复制给b数组 错误的写法: b=a; //错误 正确的写法: for (i=0;i<5;++i) b[i]=a[i];

7 7.1.4 一维数组程序举例 [例7.2]用数组来处理求Fibonacci数列问题 #include <stdio.h>
void main() { int i; int f[20]={1,1}; for(i=2;i<20;i++) f[i]=f[i-2]+f[i-1]; for(i=0;i<20;i++) if(i%5==0) printf(“\n”); printf(“%12d”,f[i]); } //int f1, f2, f3, f4; /*f1=1; f2=1; f3=f1+f2; f4=f3+f2; f5=f4+f3; .... f20=f19+f18;*/ int f[20]; f[0]=1; f[1]=1; printf("%12d", f[0]); printf("%12d", f[1]); for(int i=2; i<=19; i++) { f[i]=f[i-1]+f[i-2]; printf("%12d", f[i]); if((i+1)%5 == 0) printf("\n"); }

8 [例7.3]用起泡法对10个数排序(由小到大) 起泡法的思路:将相邻两个数比较,将小的调到前头
int a[6]={9, 8, 5, 4, 2, 0}; //用单步执行法分析一下排序的过程 for(int i=0; i<6-1; i++) { for(int j=0; j<6-i-1; j++) if(a[j] > a[j+1]) int t; t=a[j]; a[j]=a[j+1]; a[j+1]=t; } for(int k=0; k<6; k++) printf("%d ", a[k]); printf("\n");

9 冒泡法排序

10 选择法排序

11 7.2 二维数组的定义和引用 7.2.1 二维数组的定义 二维数组定义的形式为 类型说明符 数组名[常量表达式][常量表达式];
例如:float a[3][4], b[5][10]; 二维数组可被看作是一种特殊的一维数组:它的元素又是一个一维数组。 二维数组中元素排列的顺序是按行存放的。即在内存中先顺序存放第一行的元素,再存放第二行的元素。 C语言允许使用多维数组。

12

13 7.2.2 二维数组的引用 二维数组元素的表示形式为 数组名[下标][下标]
例如a[2][3]。下标可以是整型表达式,如a[2-1][2*2-1]。 数组元素可以出现在表达式中,也可以被赋值。例如: b[1][2]=a[2][3]/2 下标值应在已定义的数组大小的范围内。常出现的错误是: int a[3][4]; …… a[3][4]=3; 二维数组 int a[3][4] 总共是12个元素,可以当做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] int a[m][n] 该二维数组右下角位置的元素只能是a[m-1][n-1]

14 7.2.3 二维数组的初始化 可以用下面的方法对二维数组初始化 (1)分行给二维数组赋初值。
(2)可以将所有数据写在一个花括号内,按数组排列的顺序对各元素赋初值。 (3)可以对部分元素赋初值。 (4)如果对全部元素都赋初值(即提供全部初始数据),则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。 初始化 int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; int a[3][4]={ {1,2,3,4},{5,6,7,8},{9,10,11,12}}; int a[3][4]={{1},{0,6},{0,0,11}}; 输出二维数组内容 for (i=0;i<3;i++) { for (j=0;j<4;j++) printf(“%d”,a[i][j]); printf(“\n”); }

15 7.2.4 二维数组程序举例 [例7.4]将一个二维数组行和列的元素互换,存到另一个二维数组中。例如:

16 [例7.5]有一个3×4的矩阵,要求编程求出其中值最大的那个元素的值,以及其所在的行号和列号

17 7.3 字符数组 用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字符。

18 7.3.1 字符数组的定义 字符数组定义的一般形式为 char 数组名[常量表达式][常量表达式]……
由于字符型与整型是相互通用的,因此也可以定义一个整型数组,用它存放字符数据。 int c[10]; c[0]=‘a’; //合法,但浪费空间

19 7.3.2 字符数组的初始化 对字符数组初始化,最容易理解的方式是逐个字符赋给数组中各元素。
如果在定义字符数组时不进行初始化,则数组中各元素的值是不可预料的。 如果花括号中提供的初值个数大于数组长度,则按语法错误处理。 如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即’\0’)。 如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。 字符数组初始化方法1 char a[10]={‘I’,’ ‘,’a’,’m’,’ ‘,’’h’,’a’,’p’,’p’,’y’); //正确 等价于 char c[10]; int c[10];也是正确的 c[0]='I'; c[1]=' '; c[2]='a'; c[3]='m'; c[4]=' '; c[5]='h'; c[6]='a'; c[7]='p'; c[8]='p'; c[9]='y'; for(int i=0; i<10; i++) //打印字符串出来 printf("%c", c[i]); printf("\n");*/ char a[ ] ={‘I’,’ ‘,’a’,’m’,’ ‘,’h’,’a’,’p’,’p’,’y’); //正确,长度自动定位10

20 7.3.3 字符数组的引用 可以引用字符数组中的一个元素,得到一个字符。 [例7.6]输出一个字符串
#include <stdio.h> void main() { char c[10]={‘I’,‘a’,‘m’,‘ ‘,‘a’,‘ ‘,‘b’,‘o’,‘y’}; int i; for(i=0; i<10; i++) printf(“%c”, c[i]); printf(“\n”); }

21 [例7.7]输出一个菱形图 #include <stdio.h> void main() {
char diamond[][5]={{‘ ‘,’ ‘,’*’},{‘ ‘,’*’,’ ‘,’*’},{‘*’,’ ‘,’ ‘,’ ‘,’*’},{‘ ‘,’*’,’ ‘,’*’},{‘ ‘,’ ‘,’*’}}; int i, j; for(i=0; i<5; i++) for(j=0; j<5; j++) printf(“%c”, diamond[i][j]); printf(“\n”); }

22 7.3.4 字符串和字符串结束标志 在C语言中,是将字符串作为字符数组来处理的。字符串中的字符是逐个存放到数组元素中的。在实际工作中,人们关心的往往是字符串的有效长度而不是字符数组的长度。为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符’\0’作为标志。 系统对字符串常量也自动加一个’\0’作为结束符。字符串作为一维数组存放在内存中。

23 对C语言处理字符串的方法有以上的了解后,再对字符数组初始化的方法补充一种方法,即用字符串常量来使字符数组初始化。
字符数组初始化方法2 char a[10]=“I am happy” //正确 ,注意与char a[9]={‘I’,’ ‘,’a’,’ ‘,’h’,’a’,’p’,’p’,’y’); 方法初始化的区别,前者尾部加了一个’\0’标志。 char a[ ]=“I am happy” //正确 printf(“%s\n”,a); char a[10]; a[10]=“I am happy” //这两句是错误的,只有在初始化的时候才能进行字符串的赋值。这个地方错在先定义了一个长度为10的数组,然后给第10个元素赋一个字符串了,这显然是不正确的。

24 7.3.5 字符数组的输入输出 字符数组的输入输出可以有两种方法:
(1)逐个字符输入输出。用格式符“%c”输入或输出一个字符。(如例题7.6) (2)将整个字符串一次输入或输出。用“%s”格式符,意思是对字符串的输入输出。

25 注意: (1)输出字符不包括结束符’\0’。 (2)用“%s”格式符输出字符串时,printf函数中的输出项是字符数组名,而不是数组元素名。
(3)如果数组长度大于字符串的实际长度,也只输出到遇’\0’结束。 (4)如果一个字符数组中包含一个以上’\0’,则遇第一个’\0’时输出就结束。 (5)可以用scanf函数输入一个字符串。 (6)按字符数组名找到其数组起始地址,然后逐个输出其中的字符,直到遇’\0’为止。 2 char a[ ]=“china”; printf(“%s”,a); //正确 printf(“%s”,a[0]) ; //错误,用s参数时,输出项应该是字符数组名,而不是数组元素名。 4 char c[10]={"Ch\0in\0a"}; printf("%s\n", c);*//输出的是“Ch”,而不是10个字符,遇第一个’\0’时输出就结束。 5 Char a[6]; Scanf(“%s”,str); //正确 Scanf(“%s”,&str); //错误,数组名代表该数组第一个元素的地址,即该数组的首地址,因此在这不能使用&符号。 6 利用字符数组输入多个字符串 /*char str1[5], str2[5], str3[5]; scanf(“%s%s%s”,&str1,&str2,&str3); //错误 scanf(“%s%s%s”,str1,str2,str3); //正确,输入的字符串以空格间隔 printf("%s %s %s", str1, str2, str3); printf("%x\n", str1); printf(“%x\n”, &str1); printf(“%x\n”, &str1[0]); //以上三句是以十六进制输出,str1是数组名,存放的是第一个元素的首地址,所以在这str1和&str1、&str1[0]以十六进制输出的结果是相同的。

26 7.3.6 字符串处理函数 在C函数库中提供了一些用来处理字符串的函数,使用方便。几乎所有版本的C语言编辑系统都提供这些函数。

27 1、puts函数 函数原型: int puts(char * str); 功能:
把str指向的字符串输出到标准输出设备,将’\0’转换为换行符’\n’ 返回值: 若执行成功,返回非负值,否则,返回EOF

28 2、gets函数 函数原型: char * gets(char * str); 功能: 从终端输入一个字符串到字符数组str 返回值:
若执行成功,返回字符数组的起始地址,否则,返回NULL /*char c[20]; gets(c); printf("%s\n", c);*/

29 3、strcat函数 函数原型: char * strcat(char * str1, char * str2); 功能:
把字符串str2接到str1后面,str1最后面的’\0’被取消 返回值:str1 /*char str1[100]="hello "; char str2[]="world!"; strcat(str1, str2); printf("%s\n", str1);*/

30 4、strcpy 函数原型: char * strcpy(char * str1, char * str2); 功能:
把str2指向的字符串复制到str1中去 返回值: str1 /*char str1[100]; char str2[6]="China"; strcpy(str1, str2); printf("%s\n", str1);*/

31 5、strcmp函数 函数原型: int strcmp(char * str1, char * str2); 功能:
比较两个字符串str1、str2 返回值: str1<str2,返回负数; str1=str2,返回0; str1>str2,返回正数 //printf("%d\n", strcmp("cat", "cat"));

32 6、strlen函数 函数原型: unsigned int strlen(char * str); 功能:
返回值: 返回字符个数

33 7、strlwr函数 函数原型: char * strlwr(char * str); 功能: 将字符串str中大写字符换成小写字母
返回值: str

34 8、strupr函数 函数原型: char * strupr(char * str); 功能: 将字符串str中小写字符换成大写字母
返回值: str /*char c[]="hELLo"; printf("%s\n", strupr(c));*/

35 7.3.7 字符数组应用举例 [例7.8]输入一行字符,统计其中有多少个单词,单词之间用空格分隔开

36 [例7.9]有3个字符串,要求找出其中最大者 #include <stdio.h>
#include <string.h> void main() { char string[20]; char str[3][20]; int i; for(i=0;i<3;i++) gets(str[i]); if(strcmp(str[0],str[1])>0) strcpy(string,str[0]); else strcpy(string,str[1]); if(strcmp(str[2],string)>0) strcpy(string,str[2]); printf(“\nthe largest string is:\n%s\n”, string); }

37 习题 7.3 求一个3×3的整型矩阵对角线元素之和。 7.4 已有一个已排好序的数组,要求输入一个数后,按原来排序的规律将它插入数组中。
7.5 将一个数组中的值按逆序重新存放。例如,原来顺序为8,6,5,4,1。要求改为1,4,5,6,8。 7.6 输出以下的杨辉三角形(要求输出10行) 1 1 1 ……………....

38 7.11 输出以下图案: * * * * * * * * * * * * * * *

39 7.13 编一程序,将两个字符串连接起来,不要用strcat函数。
7.14 编一个程序,将两个字符串s1和s2比较,若s1>s2,输出一个正数;若s1=s2,输出0;若s1<s2,输出一个负数。不要用strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相应字符的ASCII码的差值。 7.15 编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中。不用strcpy函数。复制时,’\0’也要复制过去。’\0’后面的字符不复制。


Download ppt "C程序设计."

Similar presentations


Ads by Google