#includeint main() { int max(int x,int y); //对max函数的声明 int a,b,c; printf("please enter two integer numbers:"); //提示输入数据 scanf("%d,%d",&a,&b); //输入两个整数 c=max(a,b); //调用max函数,有两个实参。大数赋给变量c printf("max is %dn",c); //输出大数c return 0; } int max(int x,int y) //定义max函数,有两个参数 { int z; //定义临时变量z z=x>y?x:y; //把x和y中大者赋给z return(z); //把z作为max函数的值带回main函数 }
2.程序分析
- 定义函数,名为max,函数类型为int。指定两个形参x和y,形参的类型为int。
- 主函数中包含了一个函数调用max(a,b)。max后面括号内的a和b是实参。a和b是在main函数中定义的变量,x和y是函数max的形式参数。通过函数调用,在两个函数之间发生数据传递,实参a和b的值传递给形参x和y,在max函数中把x和y中的大者赋给变量z,z的值作为函数值返回main函数,赋给变量c。
在调用函数过程中发生的实参与形参间的数据传递称为“虚实结合”。
p191 一维数组名作函数参数 【例7.10】有一个一维数组score,内放10个学生成绩,求平均成绩。
#includeint main() { float average(float array[10]); //函数声明 float score[10],aver; int i; printf("input 10 scores:n"); for(i=0;i<10;i++) scanf("%f",&score[i]); printf("n"); aver=average(score); //调用average函数 printf("average score is %5.2fn",aver); return 0; } float average(float array[10]) //定义average函数 { int i; float aver,sum=array[0]; for(i=1;i<10;i++) sum=sum+array[i]; //累加学生成绩 aver=sum/10; return(aver); }
注意:用数组元素作实参时,向形参变量传递的是数组元素的值,而用数组名作函数实参时,向形参(数组名或指针变量) 传递的是数组首元素的地址。
程序分析
(1) 用数组名作函数参数,应该在主调函数和被调用函数分别定义数组。
(2) 实参数组与形参数组类型必须一致。
(3) 在定义average函数时,声明形参数组的大小为10,但在实际上,指定其大小是不起任何作用的,因为C语言编译系统并不检查形参数组大小,只是将实参数组的首元素的地址传给形参数组名。
(4) 形参数组可以不指定大小,在定义数组时在数组名后面跟一个空的方括号。
float average(float array[])
p196 局部变量和全局变量在复合语句内定义的变量只在本复合语句范围内有效,只有在本复合语句内才能引用它们。在该复合语句以外是不能使用这些变量的,以上这些称为“局部变量”。
在一个函数内部,可以在复合语句中定义变量,这些变量只在本复合语句中有效,这种复合语句也称为“分程序”或“程序块”。
在函数内定义的变量是局部变量,而在函数之外定义的变量称为外部变量, 外部变量是全局变量(也称全程变量)。
p212 内部函数和外部函数 如果一个函数只能被本文件中其他函数所调用,它称为 内部函数 。在定义内部函数时, 在函数名和函数类型的前面加 static ,即∶static 类型名 函数名(形参表); static int fun(int a,int b) //表示fun是一个内部函数,不能被其他文件调用如果在定义函数时,在函数首部的最左端加关键字 extern ,则此函数是外部函数,可供 其他文件调用。 如函数首部可以为
extern int fun (int a, int b)这样,函数 fun 就可以为其他文件调用。C语言规定,如果在定义函数时省略extern,则默 认为外部函数。 p215 习题3 写一个判素数的函数,在主函数输人一个整数,输出是否为素数的信息。
#includeint main() {int prime(int); int n; printf("input an integer:"); scanf("%d",&n); if (prime(n)) printf("%d is a prime.n",n); else printf("%d is not a prime.n",n); return 0; } int prime(int n) {int flag=1,i; for (i=2;i p216习题5 写一个函数,使输人的一个字符串按反序存放,在主函数中输入和输出字符串 #includeP217指针#include int main() {void inverse(char str[]); char str[100]; printf("input string:"); scanf("%s",str); inverse(str); printf("inverse string:%sn",str); return 0; } void inverse(char str[]) {char t; int i,j; for (i=0,j=strlen(str);i<(strlen(str)/2);i++,j--) {t=str[i]; str[i]=str[j-1]; str[j-1]=t; } } 内存区的每一个字节有一个编号,这就是“地址”。地址形象化地称为“指针”。
C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是"带类型的地址"。 如&a,一般称它为"变量 a的地址",确切地说,它是"整型变量 a的地址&取地址符
P218指针变量 如果有一个变量专门用来存放另一变量的地址(即指针),则它称为"指针变量"。 指针变量的值是地址(即指针)。 p223【例8.2】怎样引用指针变量 输入a和b两个整数,按先大后小的顺序输出a和b。#includeint main() { int *p1,*p2,*p,a,b; //p1,p2的类型是int *类型 printf("please enter two integer numbers:"); scanf("%d,%d",&a,&b); //输入两个整数 p1=&a; //使p1指向变量a p2=&b; //使p2指向变量b if(a p1=&a &取地址符
a==*p *取值符
p231通过指针引用数组元素【例8.6】有一个整型数组a,有10个元素,要求输出数组中的全部元素。
①下标法
#includeint main() { int a[10]; int i; printf("please enter 10 integer numbers:"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) printf("%d ",a[i]); //数组元素用数组名和下标表示 printf("%n"); return 0; } ②通过数组名计算数组元素地址,找出元素的值
#includeint main() { int a[10]; int i; printf("please enter 10 integer numbers:"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) printf("%d ",*(a+i)); //通过数组名和元素序号计算元素地址找到该元素 printf("n"); return 0; } ③用指针变量指向数组元素
#includep241 p254字符串的引用方式int main() { int a[10]; int *p,i; printf("please enter 10 integer numbers:"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(p=a;p<(a+10);p++) printf("%d ",*p); //用指针指向当前的数组元素 printf("n"); return 0; } 【例8.16】定义一个字符数组,在其中存放字符串″I love China!″,输出该字符串和第8个字符。
#includeint main() { char string[]="I love China!"; //定义字符数组sting printf("%sn",string); //用%s格式声明输出string,可以输出整个字符串 printf("%cn",string[7]); //用%c格式输出一个字符数组元素 return 0; } 【例8.17】通过字符指针变量输出一个字符串。
#includep293自己建立结构体类型int main() { char *string="I love China!"; //定义字符指针变量string并初始化 printf("%sn",string); //输出字符串 return 0; } struct Student { int num; //学号为整型 char name[20]; //姓名为字符串 char sex; //性别为字符型 int age; //年龄为整型 float score; //成绩为实型 char addr[30]; //地址为字符串 }; //注意最后有一个分号p297【例9.1】把一个学生的信息(包括学号、姓名、性别、住址)放在一个结构体变量中,然后输出这个学生的信息
#includeint main() { struct Student //声明结构体类型struct Student { long int num; //以下4行为结构体的成员 char name[20]; char sex; char addr[20]; }a={10101,"Li Lin",'M',"123 Beijing Road"}; //定义结构体变量a并初始化 printf("NO.:%ldnname:%snsex:%cnaddress:%sn",a.num,a.name,a.sex,a.addr); return 0; } 可以引用结构体变量中成员的值,引用方式为
p304 如果 p指向一个结构体变量 stu,以下3种用法等价∶ ①stu.成员名(如 stu.num); ②(*p).成员名(如(*p).num); ③ p->成员名(如 p->num)。 p310建立简单的静态链表结构体变量名.成员名
【例9.8】建立一个简单链表,它由3个学生数据的结点组成,要求输出各结点中的数据。
#includep313建立简单的动态链表struct Student //声明结构体类型struct Student { int num; float score; struct Student*next; }; int main() { struct Student a,b,c,*head,*p; //定义3个结构体变量a,b,c作为链表的结点 a.num=10101; a.score=89.5; //对结点a的num和score成员赋值 b.num=10103; b.score=90; //对结点b的num和score成员赋值 c.num=10107; c.score=85; //对结点c的num和score成员赋值 head=&a; //将结点a的起始地址赋给头指针head a.next=&b; //将结点b的起始地址赋给a结点的next成员 b.next=&c; //将结点c的起始地址赋给a结点的next成员 c.next=NULL; //c结点的next成员不存放其他结点地址 p=head; //使p指向a结点 do { printf("%ld %5.1fn",p->num,p->score); //输出p指向的结点的数据 p=p->next; //使p指向下一结点 }while(p!=NULL); //输出完c结点后p的值为NULL,循环终止 return 0; } 【例9.9】写一函数建立一个有3名学生数据的单向动态链表。
#include#include #define LEN sizeof(struct Student) struct Student { long num; float score; struct Student*next; }; int n; //n为全局变量,本文件模块中各函数均可使用它 struct Student *creat(void) //定义函数。此函数返回一个指向链表头的指针 { struct Student *head; struct Student *p1,*p2; n=0; p1=(struct Student*) malloc(LEN); //开辟一个新单元 scanf("%ld,%f",&p1->num,&p1->score); //输入第1个学生的学号和成绩 head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct Student*)malloc(LEN); //开辟动态存储区,把起始地址赋给p1 scanf("%ld,%f",&p1->num,&p1->score); //输入其他学生的学号和成绩 } p2->next=NULL; return(head); } int main() { struct Student *pt; pt=creat(); //函数返回链表第一个结点的地址 printf("nnum:%ldnscore:%5.1fn",pt->num,pt->score); //输出第1个结点的成员值 return 0; };



