第一篇:C语言程序设计教案 第十章指针
第十章 指 针
课题:
教学目的: 教学重点: 教学难点: 第十章 指针
§1-§2
1、了解指针与地址的概念
2、掌握指针变量的定义、初始化及指针的运算 指针变量的定义、初始化及指针的运算
指针的运算
步骤一 复习引导
指针是C语言的一个重要概念,也是C语言的一个重要特色。正确而灵活地运用它,可以有效地表示复杂的数据结构;能动态分配内存;能方便地使用字符串;有效而方便地使用数组;在调用函数时能得到多于1个的值;能直接处理内存地址等,这对设计系统软件是很必要的。
指针的概念比较复杂,使用也比较灵活,因此初学者时常会出错,务请在学习本章内容时十分小心。
步骤二 讲授新课
§10.1 地址和指针的概念
计算机的主存储器被分成一个个存储单元,为了区分各存储单元,要为每个存储单元编号,这个编号即地址。
例:i =3;
或 scanf(“%d”, &i);
是将3送给 i所在的空间。
例:将3送到变量I_pointer所“指向”的单元(即I所标志的单元)。
所谓“指向”,是通过地址来体现的,I_pointer中的值为2000,它是变量I 的地址,这样就在I_pointer和变量之间建立起一种联系,即通过I_pointer能知道I的地址,从而找到变量I的内存单元。因而在C语言中,将地址形象化地称为“指针”。
意思是通过它能找到以它为地址的内存单元。一个变量的地址称为该变量的“指针”。
内存单元的地址和内存单元的内容是两个不同的概念。
指针:就是地址,即内存单元的编号。
指针变量:用来存放另一变量的地址(即指针)的变量。
如:地址2000是变量 i的指针;i_pointer是指针变量,其值就是指针2000。
§10.2变量的指针和指向变量的指针变量
变量的指针就是变量的地址。
存放变量地址的变量是指针变量,用来指向另一个变量。
*i_pointer 表示 i_pointer 所指向的变量。
一、定义一个指针变量
指针变量的定义包含三个方面的内容:
⑴ 指针类型说明,即定义变量为一个指针变量 ⑵ 指针变量名
⑶ 变量值(指针)所指向的变量的数据类型。格式:
存储类型
基类型
*指针变量名;例:int *pointer_1, *pointer_2;
float *pointer_3;
char *pointer_4;
二、指针的引用
指针变量有两个运算符: & :取地址运算符
功能:取变量地址;单目,右结合。
* :取内容运算符(“间接访问”运算符)
功能:只能跟地址,取变量所指向单元的内容;单目,右结合。
例:&a为变量a的地址,*p 为指针变量p所指向的存储单元。
例:int a=5, *p=&a;
printf(“%d”, *p);main(){ int a,b;
int *pointer_1,*pointer_2;
a=100;b=10;
pointer_1=&a;
/*把变量a的地址赋给pointer_1*/
pointer_2=&b;
/*把变量b的地址赋给pointer_2*/
printf(“%d,%dn”,a,b);
printf(“%d,%dn”,*pointer_1, *pointer_2);} 输出结果:100, 10
100, 10
评注:
1、在第3行虽然定义了两个指针变量,只是提供了两个指针变量,但并未指向任何一个整型变量。称为指针“悬空”。
2、最后一行的*pointer_1和pointer_2就是变量a和b。
3、程序中两处出现*pointer_1等,含义不同。程序第3行中的*pointer_1表示定义指针变量pointer_1。它前面的*只是表示该变量是指针变量。程序最后一行中的*pointer_1则代表变量,即pointer_1所指向的变量。
4、第5行中的pointer_1=&a 是将a的地址赋给指针变量pointer_1,而不是*pointer_1。
注意:不应写成:*pointer_1=&a;
5、从上例中可看出,*pointer_1等价于a,*pointer_2等价于b,故凡在程序中出现a的地方均可用 *pointer_1 代替。所以,若有: int x, y, *px=&x;则下面的运算均是正确的: y=*px+1;
/*把 x 的内容加1 送变量y*/ printf(“%dn”, px);
/*打印当前x 的内容*/ d=sqrt((double)px);
/*把x的平方根送变量d*/ px=0;
/*把 x 置为0*/ *px+=1;
/*把 x 的值加 1*/(*px)++;
/*使 x 的值加 1*/ y=(*px)++;
/*即y=x, x++*/
6、假设px和py都被定义为指向int 对象的指针,而且px当前已指向了int 型变量x,则执行:
py=px;
/*把指针px的内容拷贝到指针py中去*/ 即
py和px 这两个不同的指针指向了同一对象x
7、指针不是整数,不能将它与整数混为一谈。例:
# include
例如:
# include
b = d;
printf(“%d n”, b);
……
}——编译不出错,但得不到希望的值
关于&和*运算符的说明:
假设已执行
pointer_1=&a;
1、&*pointer_1含义是什么?
&*pointer_1与&a相同,即变量a的地址。
2、*&a的含义是什么?
先进行&a运算,得a的地址,再进行*运算。
*&a、*pointer_1及变量a等价。
3、(*pointer_1)+ + 相当于a + +。
它与*pointer_1 + + 不同。
4、*pointer_1 + + 等价于*(pointer_1 + +),即先进行*运算,得到a的值,然后使pointer_1的值改变,这样pointer_1不再指向a了。
例10.2:输入a和b两个整数,按先大后小的顺序输出a和b。
main(){ int *p1,*p2,*p, a, b;
scanf(“%d,%d”,&a,&b);
p1=&a;p2=&b;
if(a
{p=p1;p1=p2;p2=p;}
printf(“n a=%d,b=%dn”,a,b);
printf(“max=%d,min=%dn”,*p1,*p2);
} 运行情况: 5,9
三、指针变量作为函数参数
例10.3对输入的两个整数按大小顺序输出。先考察如下程序,看是否能得到预期的结果
swap(int p1, int p2){ int temp;temp = p1;p1 = p2;p2 =temp;} main(){ int a, b;
scanf(“%d, %d”, &a, &b);
if(a
printf(“n%d,%dn”,a,b);} 不能得到预期的结果。改为:
swap(int *p1,int *p2){ int temp;
temp = *p1;
*p1 = *p2;
*p2 =temp;} main(){ int a,b;
int *pointer_1,*pointer_2;
scanf(“%d,%d”,&a,&b);
pointer_1=&a;
pointer_2=&b;
if(a
swap(pointer_1,pointer_2);
printf(“n%d,%dn”,a,b);}
注:如果想通过函数调用得到n个改变的值,可以:
1、在主调函数中设n 个变量,用n个指针变量指向它们;
2、然后将指针变量作实参,将这n 个变量的地址传给所调用的函数的形参;
3、通过形参指针变量,改变该n个变量的值;
4、主调函数中就可以使用这些改变了值的变量。
四、指针(变量)的初始化 指针置初始化值的格式:
存储类型
基类型
*指针名=初始化值; 如:main()
{ static int a;
int *p=&a, *p1=p;
…… } 再如: int *p = 0;
或
int *p = NULL;
五、指针的运算
1、指针的算术运算
指针仅能进行加、减算术运算
如:p+n , p-n , p++ , p--, ++p ,--p
p-= n , p+= n , p1-p2 等 其中n是整数,p、p1、p2均为指针;
施行加法运算时,指针向地址增大的方向移动; 施行减法运算时,指针向地址减小的方向移动; 移动长度取决于指针的基类型,由计算机决定; 如有:int a,b,c, *pt =&a;
则
pt++ 则指针向后移动两个字节; 再如:main()
{ int *p1,a=8,b=3;
p1=&a;
printf(“%d,%dn”,(*p1)++, *p1++);
printf(“%d,%dn”,a, *p1);
} 运行结果:3,8,4 注:p1+k = p1+k*sizeof(p1的基类型);
p1-k = p1-k*sizeof(p1的基类型);如:
strlen(char *s)
{ char *p=s;
while(*p!=„ ‟)p++;
return(p-s);
}
2、指针的关系运算
设指针p1,p2指向同一数组中的元素,则
p1
p1
p1= =p2:
表示p1、p2指向数组中的同一元素;
同理可推出>、>=、<=、!=比较的意义; 不可将指针与其他类型的对象作比较;
若两指针指向不同数组中的元素,也不可比较;
允许将指针与NULL或数值0进行= =或!=的比较,以便判定一个指针是否为空指针。
步骤三 课堂小结
本课介绍了指针与地址的概念,指针变量的定义、初始化及指针的运算。
指针:就是地址,即内存单元的编号。
指针变量:用来存放另一变量的地址(即指针)的变量。
例如:int a=5, *p=&a;
printf(“%d”, *p);
注意:运算符*和&的用法,指针变量的自加自减运算。步骤四 布置作业
课后作业:第十章课后练习10.1 10.2 课题:
教学目的: 教学重点: 教学难点: 第十章 指针
§3 掌握指针与数组的知识 指向数组的指针变量
指向二维数组的指针
步骤一 复习引导
上节课介绍了指针变量的定义及其赋值。一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组和数组元素(把数组起始地址或某一元素的地址放到一个指针变量中)。
步骤二 讲授新课
所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。
引用数组元素可以用下标法(如a[3]),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占内存少,运行速度快)。
一、指向一维数组的指针
定义形式:
int a[10];
int *p;
p=&a[0];
或
p=a;
含义:把数组的首地址赋给指针变量p。
也即: int *p=&a[0];
或
int *p=a;
二、通过指针引用数组元素
按C的规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一个数组中的下一个元素(而不是简单地加1)。
如果p的初值为&a[0],则:
p+i a+i &a[i],即指向a数组的第i个元素。
*(p+i) *(a+i)
a[i]。
指向数组的指针变量也可以带下标,如p[i]与*(p+i)等价 引用数组元素时,可以用:
1、下标法,如:a[i]
2、指针法,如:*(a+i)
或
*(p+i)
其中,a是数组名,p是指向数组的指针
例10.5:输出数组中的全部元素
假设有一个a数组,整型,有10个元素。用三种方法输出各元素的值:
1、下标法: main(){ int a[10], i;
for(i=0;i<10;i++)
scanf(“%d”,&a[i]);
printf(“n”);
for(i=0;i<10;i++)
printf(“%d”,a[i]);}
2、利用数组名计算数组元素地址,找出元素的值。main(){ int a[10], i;
for(i=0;i<10;i++)
scanf(“%d”,&a[i]);
printf(“n”);
for(i=0;i<10;i++)
printf(“%d”,*(a+i));}
3、用指针变量指向数组元素。main(){ int a[10], *p, i;
for(i=0;i<10;i++)
scanf(“%d”,&a[i]);
printf(“n”);
for(p=a;p<(a+10);p++)
printf(“%d”,*p);} 评注:
1、第1和2种方法执行效率是相同的。
2、第3种方法效率高。
3、用下标法比较直观。
在使用指针变量时,有几个问题要注意:
1、指针变量可以实现使本身的值改变。如:for(p=a;p<(a+10);p++)
2、要注意指针变量的当前值。
如:要通过指针变量输出a数组的10个元素。main(){ int a[10], i , *p=a;
for(i=0;i<10;i++)
scanf(“%d”, p++);
printf(“n”);
for(i=0;i<10;i++,p++)
printf(“%d”, *p);} 这个程序输出的并不是a数组中各元素的值。因为第一个 for 循环结束时,p已经指向数组的末尾。再继续下去,p指向的是a数组下面的10个元素,是不可预料的。可加一句为:p=a;
3、用指针变量p指向数组元素,可以指到数组以后的内存单元。C编译程序不作下标越界检查。
4、注意指针变量的运算。如果p指向数组a,⑴ p++(或 p+=1),使p指向下一元素a[1]。⑵ *p++
等价 *(p++)。作用是先得到p指向的变量的值(即*p),然后再使p+1→p。⑶ *(p++)与*(++p)不同。前者为a[0],后者为a[1] ⑷(*p)++表示p指向的元素值加1,即(a[0])++ ⑸ 如果p当前指向a数组中第i个元素,则:
*(p--)相当于a[i--],先对p进行*运算,再使p自减; *(+ + p)相当于a[+ +i],先使p自加,再作*运算。*(-){ temp=*i;*i = *j;*j =temp;} return;} main(){ int i, a[10],*p=a;printf(“The original array: n ”);for(i=0;i<10;i++,p++)scanf(“%d”, p);printf(“n”);p=a;inv(p,10);printf(“The array is : n”);for(p=a;p 例10.10:用选择法对10个整数排序。main(){int *p, i, a[10];p=a;for(i=0;i<10;i++)scanf(“%d”,p++);p=a;sort(p,10);for(p=a, i=0;i<10;i++){ printf(“%d”,*p);p++;} } sort(int x[],int n){ int i, j, k, t;for(i=0;i 四、指向二维数组的指针和指针变量 1、二维数组的地址如: int a[3][4] A a[0] a[0] [0] a[0] [1] a[0] [2] a[0] [3] A+1 a[1] a[1] [0] a[1] [1] a[1] [2] a[1] [3] A+2 a[2] a[2] [0] a[2] [1] a[2] [2] a[2] [3] 例:int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; 设首地址为2000。 a[k]+p(0<=k< i , 0<=p a+k与&a[k][0]等价,而a[0]+k与&a[0][k]等价; *(a+i)可理解为a[i],故有如下等价关系: a+0 等价于 a[0]、a[0]+0、&a[0][0]、*(a+0) a+1 等价于 a[1]、a[1]+0、&a[1][0]、*(a+1) a+(i-1)等价于 a[i-1]、a[i-1]+0、&a[i-1][0]、*(a+i-1) *(a+k)与*a[k]是不同的,前者相当于a[k],是一个地址值;后者相当于*(a[k]+0)或*&a[k][0],是数组元素a[k][0]中存储的值。 数组元素a[k][p]就是*(a[k]+p),即*(*(a+k)+p) 步骤三 课堂小结 本课介绍了指向数组的指针,主要是指向一维数组的指针。用指针变量p指向数组a,指针变量p可以++、--,表示指向数组的上一元素或下一元素。但C编译程序不作下标越界检查。使用指针既方便有灵活,但初学者容易搞错。 步骤四 布置作业 课后作业:第十章课后练习10.31 10.5 课题: 教学目的: 教学重点: 教学难点: 第十章 指针 §3-§4 在掌握指针与数组的基础上,掌握字符串的指针与指向字符串的指针变量 指向字符串的指针变量 用指针处理字符串 步骤一 复习引导 上节课介绍了指向一维数组的指针及二维数组的地址,指向一维数组的指针也即指向元素的指针,那么指向二维数组的指针是怎样的呢?它有两种类型。 步骤二 讲授新课 2、指向二维数组的指针变量 ——(1)指向数组元素的指针变量 设指针变量p=a[0] (&a[0][0]、a、a+0、*(a+0))计算a[i][j]在n*m数组中的位置: 例:…… for(i=0;i<3;i++) {for(j=0;j<4;j++)printf(“%4d”, *(p+i*m+j)); printf(“n”);} …… 例:用指针变量输出数组元素的值。main(){ int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int *p; for(p=a[0];p {if((p-a[0])%4 == 0)printf(“n”); printf(“%4d”, *p); } } 计算a[i][j]在n*m数组中的位置:a[0]+i*m+j ——(2)行指针(指向由m个元素组成的一维数组的指针变量) 定义:指针基类型 (*指针名)[m] 其中,m表示二维数组每行有m列; 如: int(*p)[3]; 于是,p 指向第0行元素的起始存储地址; p+1 指向第1行元素的起始存储地址;…… p+I 指向第i 行元素的起始存储地址; 而每一行的元素的表示形式为: 第0行元素的表示为(*p)[j]; 第1行元素的表示为(*(p+1))[j];…… 第i 行元素的表示为(*(p+ I))[j]; 例 : #include int a[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};for(p=a;p for(j=0;j<4;j++) if(j==3)printf(“%4dn”,(*p)[j]); else printf(“%4d” ,(*p)[j]); } 改写为: #include int a[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; p=a; for(i=0;i<4;i++) for(j=0;j<4;j++) printf(j==3?“%4dn”: “%4d” , *(*(p+i)+j)); } 3、多维数组的指针作函数参数 一维数组的地址可以作为函数参数传递,多维数组的地址也可作函数参数传递。在用指针变量作形参以接受实参数组名传递来的地址时,有两种方法: 1、用指向变量的指针变量; 2、用指向一维数组的指针变量。 例;有一个班,3个学生,各学4门课,计算总平均分数,以及第n个学生的成绩。main(){ void average(float *p ,int n); void search(float(*p)[4], int n); float score[3][4]={{65,67,70,60},{80,87,90,81}, {90,99,100,98}}; average(*score, 12); /*求12个分数的平均分*/ search(score , 2); /*求第2个学生成绩*/ } void average(float *p , int n){float *p_end; float sum= 0,aver; p_end = p+n-1; for(;p<=p_end;p++)sum =sum+(*p);aver = sum/n;printf(“average=%5.2fn”,aver);} void search(float(*p)[4], int n){ int i;printf(“the score of No %d are:n”,n);for(i=0;i<4;i++)printf(“%5.2f”, *(*(p+n)+i));} 例10.15 在上题基础上,查找一门以上课程不及格的学生,打印出他们的全部课程的成绩。main(){ void search(float(*p)[4], int n);float score[3][4]={{65,57,70,60},{58,87,90,81),{90,99,100,98}};search(score, 3);} void search(float(*p)[4], int n){int i, j, flag;for(j=0;j §10.4字符串的指针和指向字符串的指针变量 一、字符串的表示形式 1、用字符数组存放一个字符串。如:main() { char string[ ]=“I love China!”; printf(“%sn”, string);} 2、用字符指针指向一个字符串。 如:main() { char *string=“I love China!”; printf(“%sn”, string);} 例10.18 将字符串a复制为字符串b。main(){ char a[]=“I am a boy.” , b[20]; int i; for(i=0;*(a+i)!=„ ‟;i++)*(b+i)= *(a+i); *(b+i)= „ ‟; printf(“string a is : %sn”, a); printf(“string b is :”); for(i=0;b[i]!=„ ‟;i++) printf(“%c”, b[i]); printf(“n”);} 例10.19 用指针变量来处理上例。main(){ char a[ ]=“I am a boy.” , b[20], *p1, *p2; int i; p1= a;p2= b; for(;*p1!=„ ‟;p1++,p2++)*p2 = *p1; *p2 = „ ‟; printf(“string a is : %sn”, a); printf(“string b is :”); for(i=0;b[i]!=„ ‟;i++) printf(“%c”, b[i]); printf(“n”);} 二、字符串指针作函数参数 例10.20:用函数调用实现字符串的复制。——(1)用字符数组作参数。 void copy_string(char from[],char to[]){ int i=0; while(from[i]!=„ ‟) { to[i] = from[i];i++;} to[i]=„ ‟; } main(){ char a[]=“I am a teach.”; char b[]=“you are a student.”; printf(“string a= %snstring b=%sn”,a,b); copy_string(a,b); printf(“nstring a=%snstring b=%sn”,a,b);} ——(2)形参用字符指针变量 void copy_string(char *from,char *to){ for(;* from!=„ ‟;from++, to++) *to = *from; *to=„ ‟; } ——(3)对copy_string函数还可以简化。① void copy_string(char *from, char *to) { while((*to =* from)!=„ ‟) { to ++;from++;} } ② void copy_string(char *from, char *to) { while((*to ++ =* from++)!=„ ‟);} ③void copy_string(char *from, char *to) { while(* from!=„ ‟) *to++ = *from ++; *to = „ ‟; } ④void copy_string(char *from, char *to) { while(*to++ = *from ++);} ⑤void copy_string(char *from, char *to) { for(;*to++ = *from ++;);} ⑥void copy_string(char from[], char to[]) { char *p1,*p2; p1=from;p2=to; while((*p2++ = *p1++)!=„ ‟); } 三、字符指针变量和字符数组的讨论 1、字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,决不是将字符串放到字符指针变量中。 2、赋值方式。对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值; char str[14]; str=“I love China.”;对字符指针变量,可以采用下面方法赋值: char *a; a= “I love China.”; /*赋给a的是串的首地址*/ 3、对字符指针变量赋初值: char *a=“I love China.”; 等价于 char *a; a=“I love China.”; 而对数组的初始化: char str[14]={“I love China.”};不等价于 char str[14]; str[]=“I love China.”; 即数组可以在变量定义时整体赋初值,但不能在赋值语句中整体赋值。 4、如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。而定义一个字符指针变量时,给指针变量分配内存单元,在其中可以放一个地址值,也就是说,该指针变量可以指向一个字符型数据,但如果未对它赋一个地址值,则它并未具体指向一个确定的字符数据。这很危险。 如: char str[10]; scanf(“%s”,str);是可以的 char *a; scanf(“%s”,a); 能运行,但危险,不提倡,在a单元中是一个不可预料的值。 应当 char *a,str[10];a=str;scanf(“%s”,a); 5、指针变量的值是可以改变的,数组名虽然代表地址,但它的值是不能改变的。可以下标形式引用所指的字符串中的字符。 如:main() {char *a=“I love China.”; a=a+7; printf(“%s”,a);} 又如:char str[]={“I love China.”};str=str+7;printf(“%s”,str);是错的 6、用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串。也可以用字符数组实现,但由于不能采用赋值语句对数组整体赋值。 如:char *format;format=“a=%d,b=%fn”;printf(format,a,b); 等价于:printf(“a=%d,b=%fn”,a,b); 也可以:char format[ ]=“a=%d,b=%fn”;printf(format,a,b); 步骤三 课堂小结 本课介绍了指针与二维数组、指针与字符串,指向二维数组的指针有指向元素的指针和行指针,使用时应注意它们的区别。我们既要掌握用数组处理字符串,也要掌握用指针变量处理字符串。要区分这两种方法的不同之处。 步骤四 布置作业 课后作业:第十章课后练习10.61 10.7 课题: 第十章 指针 §5-§7 教学目的: 了解指针与函数的概念 教学重点: 教学难点: 指针数组,二级指针 掌握指针数组,二级指针等知识 掌握指针数组,二级指针等知识 步骤一 复习引导 前面介绍了指针与维数组、指针与字符串,我们可以用指针变量指向整型变量、字符串、数组,也可以指向一个函数。 步骤二 讲授新课 §10.5函数的指针和指向函数的指针变量 函数的地址:函数存储区域的首地址就是该函数的入口点,其函数名表示了入口地址。 一、函数指针变量的定义: 存储类型 数据类型 (*函数指针名)(); 例:static int(*p)();例10.23 求a和b中的大者。 main() { int max(int, int); int a,b,c; scanf(“%d,%d”,&a,&b); c=max(a,b); printf(“a=%d,b=%d,max=%d”,a,b,c); } max(int x, int y){ int z; if(x>y)z=x; else z=y; return(z);} 法2:main() { int max(int, int); int(*p)(); int a,b,c; p=max; /*将地址送入p */ scanf(“%d,%d”,&a,&b); c=(*p)(a,b); /*与max(a,b)等价*/ printf(“a=%d,b=%d,max=%d”,a,b,c); } 注:int(*p)()定义p是一个指向函数的指针变量,此函数带回整型的返回值。 说明: 1、函数的调用可以通过函数名调用,也可以通过函数指针调用。 2、(*p)()表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。 3、在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:p=max。 4、用函数指针变量调用函数时,只需将(*p)代替函数名即可(p为指针变量名),在(*p)之后的括号中根据需要写上实参。如:c=(*p)(a,b); 5、对指向函数的指针变量,像p+n、p++、p--等运算是无意义的。 二、用指向函数的指针作函数参数 函数的参数可以是变量、指向变量的指针变量、数组名、指向数组的指针变量等。现介绍指向函数的指针也可以作为参数,以便实现函数地址的传递,也就是将函数名传给形参。 它的原理可以简述如下:有一个函数(假设函数为sub),它有两个形参(x1和x2),定义x1和x2为指向函数的指针变量。在调用函数sub时,实参用两个函数名f1和f2给形参传递函数地址。这样在函数sub中就可以调用f1和f2函数了。 有人会问,既然在sub函数中要调用f1和f2函数,为什么不直接调用f1和f2而用函数指针变量呢?的确,如果只是用到f1和f2,完全可以直接在sub函数中直接f1和f2,而不必设指针变量x1、x2。但是,如果在每次调用sub函数时,要调用的函数是不固定的,这次调用f1和f2,而下次要调用f3和f4,第三次要调用的名作为实参即可,sub函数不必作任何修改。这种方法是符合结构化程序设计方法原则的,是程序设计中常使用的。 例10.24 设一个函数process,在调用它的时候,每次实现不同的功能。 main(){ int max(int ,int); int min(int , int); int add(int , int); int a, b; printf(“enter a and b:”); scanf(“%d,%d”, &a, &b); printf(“max=”);process(a,b,max); printf(“min=”);process(a,b, min); printf(“sum=”);process(a,b, add);} max(int x, int y) { int z; if(x>y)z = x;else z = y; return(z); } min(int x, int y) { int z; if(x else z = y; return(z);} add(int x, int y){ int z; z = x+y; return(z);} process(int x, int y, int(*fun)(int ,int)){int result; result =(*fun)(x,y); printf(“%dn” , result);} 在函数process定义中,int(*fun)(int,int)表示fun是指向函数的指针,该函数是一个整型函数,有两个整型形参。 在三次调用中,分别将函数名max、min、add作为实参将其入口地址送给process函数中的形参fun(fun是指向函数的指针变量)。例:process函数中的(*fun)(x,y)相当于max(x,y)。 注:在使用时,应将函数声明,这样编译系统将它按函数名处理(把函数入口地址作实参值),而不是作为变量名,不致出错。 Process函数无固定功能。如果max、min、add换成其它函数,此process函数不需改变,只要修改每函数的函数体。 §10.6 返回指针值的函数 一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。其概念与以前类似,只是带回的值的类型是指针类型而已。格式: 类型名 *函数名(参数表);例: int *a(int x, int y); a是函数名,调用它以后能得到一个指向整型数据的指针(地址)。 例10.25 有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号以后,能输出该学生的全部成绩。用指针函数来实现。float *search(float(*pointer)[4], int n) {float *pt; pt = *(pointer +n); return(pt); } main(){ float score[][4]={{60,70,80,90},{56,89,67,88),{34,78,90,66}}; float *p; int i, m; printf(“enter the number of student:”); scanf(“%d”,&m); printf(“The score of No.%d are:n”, m); p=search(score, m); for(i=0;i<4;i++) printf(“%5.2t”, *(p + i)); } 例10.26 对上例中的学生,找出其中有不及格课程的学生及其学生号。float *search(float(*pointer)[4]){ int i; float *pt; pt = *(pointer+1); for(i=0;i<4;i++) if(*(*pointer+i)<60)pt = *pointer; return(pt);} main(){ score[][4]={{60,70,80,90},{56,89,67,88),{34,78,90,66}}; float *search(float(*pointer)[4], int n); float *p; int i, m; for(i=0;i<3;i++){ p=search(score+i); if(p==*(score + i)) { printf(“ No.%d score:”, i); for(j=0;j<4;j++) printf(“%5.2t”, *(p + i)); printf(“n”);} } } 关于函数的返回值是指针的情况,程序设计时应注意: 1、因数组名是地址常量,用于接受这种返值的对象不能是数组名,这与把数组名作为实在参数传递给形式参数的情况不同(作为形式参数的数组名总被视为指针)。 2、不应将局部于被调用函数的指针作为返值返回给调用者,理由是局部于被调用函数的数据对象执行返回语句离开被调用函数后,原来分配的被调用函数的所有局部对象的存储空间立即被收回(释放),虽然调用者已经获得了正确的地址值,但此时它指向的存储区域的内容可能已经发生了变化,或许已经分配给其他函数了。如果调用函数中仍然使用这个指针去存取那个区域中的数据,得到的可能并非原先的数据。对于这种情况的正确做法是应该把所处理的对象定义成全局对象或static型对象。 §10.7 指针数组和指向指针的指针 一、指针数组的概念 一个数组中的元素均为指针类型,称为指针数组。 形式: 存储类型 类型名 *数组名[数组长度] 例如: static int *p[4] 定义指针数组时也可以进行初始化,如: static char ch[][20]={“Beijing”,“Nanjing”,“Shanghai”,“Guangzhou”}; char *p[ ]={ch[0],ch[1],ch[2],ch[3]};该例也可以等价定义为: char *p[ ]={“Beijing”,“Nanjing”,“Shanghai”,“Guangzhou”}; 例如: main(){ int i, min, j; char *temp, *p[ ]={“Beging”,“Nanjing”,“Shanghai”, “Guangzhou”}; for(i=0;i<3;i++) { min=i; for(j=i+1;j<4;j++) if(strcmp(p[j], p[min])<0)min=j; temp=p[i];p[i]=p[min];p[min]=temp; } for(i=0;i<4;i++) printf(“%sn”, p[i]);} 注意:不能把一个二维数组与一个指针数组混淆; 如:int a[10][10];与 int *b[10];的异同点 访问形式相同;如a[5][5],b[5][5]; 占用的存储空间数不同; 每一个b[i]必须置初值者能使用; 使用b优越 不需进行复杂的下标计算; b[i]指向的数组并非一定要10个元素,但a中,每一行上的元素个数必须相同;因指针指向的是一个地址,故对b而言,各个b[i]指向的存储区域之间不必连续;而对a而言,必须存储100个连续的存储int型数据对象的区域。 例10.27 将若干字符串按字母顺序(由小到大)输出。main(){ void sort(char *name[], int n); void print(char *name[], int n); char *name[]={“Follow me”, “Basic”, “Great Wall”, “Fortran”, “Computer”}; int n=5; sort(name, n); print(name, n); } void sort(char *name[], int n){ char *temp; int i, j, k; for(i=0;i { k=i; for(j=i+1;j if(strcmp(name[k], name[j])>0)k=j;if(k!=i) {temp=name[i]; name[i]=name[k]; name[k]=temp;} } } void print(char *name[], int n);{ int i; for(i=0;i } 二、指向指针的指针 在本章开头已提到“间接访问”变量的方式。利用指针变量访问另一个变量就是“间接访问”。 如果在一个指针变量中存放一个目标变量的地址,这就是“单级间址”。指向指针的指针用的是“二级间址”方法。从理论上讲,间址方法可以延伸到更多的级。但实际上在程序中很少有超过二级间址的。级数愈多,愈难理解,容易产生混乱,出错机会也多。 二级指针的定义: char **p; 含义:表示指针变量p是指向一个字符指针变量(即指向字符型数据的指针变量)的。main(){ int i, min, j; char *temp, *p[ ]={“Beging”,“Nanjing”,“Shanghai”, “Guangzhou”}; char **pp; pp=p; for(i=0;i<3;i++) { min=i; for(j=i+1;j<4;j++) if(strcmp(*(pp+j),*(pp+min))<0)min=j; temp=*(pp+i); *(pp+i)=*(pp+min); *(pp+min)=temp; } for(i=0;i<4;i++)printf(“%sn”,*pp++);} 例10.28 使用指向指针的指针。main(){ char *name[]={“Follow me”, “Basic”, “Great Wall”, “Fortran”, “Computer”}; char **p; int i; for(i=0;i<5;i++) { p=name+i; printf(“%sn”, *p); } } 例 main(){ static int a[5]={1,3,5,7,9}; int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]}; int **p, i; p= num; for(i=0;i<5;i++) { printf(“%dt”, **p); p++; } } 运行结果: 步骤三 课堂小结 本课介绍了指针数组、二级指针、指针与函数。要搞清它们的定义及应用; 注意区分: char a[5]; 与 char(*a)[5]; int *p(int x); 与 int(*p)(); 步骤四 布置作业 《C语言习题集》同步练习课题: 第十章 指针 §7-§8 教学目的: 了解指针数组作main函数的形参 教学重点: 教学难点: 指针的应用 掌握指针的应用 掌握指针的应用 步骤一 复习引导 上节课介绍了二级指针、指针数组,而指针数组的一个重要应用是作为main函数的形参。main()函数是我们C语言程序必不可少的,以往使用时main()是不带参数的。实际上是可带参数的,如:main(argc, argv)。 步骤二 讲授新课 三、指针数组作main函数的形参 带参数的main原型: main(int argc, char *argv[ ]) { …… } 说明: 第1个参数是指命令行中参数的个数,含文件名本身。 第2个参数是一个指向字符串的指针数组。 main函数是由系统调用的。当处于操作命令状态下,输入main所在的文件名(经过编译、连接后得到的可执行文件名),系统就调用main函数。参数应和命令一起给出。命令形式: 命令名 参数1 参数2 ……参数n 例如:有一个目标文件名file1,今想将两个字符串“China”, “Beijing”作为传送给main函数的参数。可写成: file1 China Beijing 例:编写一程序echo.c,实现将命令行上除程序名之外的所有给出的其他参数都回显到显示器上。 main(int argc, int *argv[ ]){ while(argc>1){ ++argv; printf(“%s”, *argv); --argc;} } 若将该程序编译、连接、装配成echo.exe,则在命令行上输入: echo hello, world! §10.8有关指针的数据类型和指针运算的小结 一、有关指针的数据类型的小结 见书中的表 二、指针运算小结 1、指针变量加(减)一个整数 例:p++、p--、p+i、p-=I等 2、指针变量赋值 将一个变量地址赋给一个指针变量。p=&a;p1=p2; 3、指针变量可以有空值,即该指针变量不指向任何变量。如 : p=NULL; 4、两个指向同一数组元素的指针变量可以相减 5、两个指向同一数组的指针变量可作关系运算 习题举例: 习题10.4 有n个整数,使其前面各数顺序向右移m个位置,最后m个数变成最前面m个数。写一函数实现以上功能,在主函数中输入n个整数,并输出调整后的n个数。 main(){ int number[20],n,m,I; printf(“How many number?”); scanf(“%d”,&n); printf(“Input %d number:n”,n); for(i=0;i scanf(“%d”,&number[i]); printf(“How many place you want to move?”); scanf(“%d”,&m); move(number, n, m); printf(“Now,they are:n”); for(i=0;i printf(“%d”, number[i]);} move(int array[20], int n, int m){ int *p,array_end; array_end = *(array+n-1); for(p= array+n-1;p>array;p--) *p= *(p-1); *array=array_end; m--; if(m>0)move(array, n, m);} 习题10.5 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。程序: main(){ int i, k, m, n, num[50], *p; printf(“Input number of person:n=”); scanf(“%d”,&n); p=num; for(i=0;i *(p+i)= i+1; i=0;k=0;m=0; while(m { if(*(p+i)!=0)k++; if(k==3) { *(p+i)=0;k=0;m++;} i++; if(i= =n)i=0; } while(*p==0)p++; printf(“The last one is NO.%dn”,*p); } 习题10.6 写出一个函数,求一个字符串的长度。在main函数中输入字符串,并输出其长度。main(){ int len; char *str[20]; printf(“Input string:”); scanf(“%s”, str); len=length(str); printf(“The length of string is %d.”,len);} length(char *p){ int n; n=0; while(*p!=„ ‟) { n++; p++; } return(n);} 习题10.7 有一字符串,包含n个字符。写一个函数,将此字符串中从第m个字符开始的全部字符复制成为另一个字符串。main(){ int m; char *str1[20],*str2[20]; printf(“Input string:”); gets(str1); printf(“Which character that begin to copy?”); scanf(“%d”,&m); if(strlen(str1) printf(“Input error!”); else { copystr(str1,str2,m); printf(“result:%s”,str2); } } copystr(char *p1, char *p2, int m){ int n; n=0; while(n {n++; p1++; } while(*p1!=„ ‟) { *p2 = *p1; p1++;p2++; } *p2=„ ‟;} 习题10.9 写一个函数,将3×3的矩阵转置。main(){ int a[3][3],*p, i; printf(“Input matrix:n”); for(i=0;i<3;i++)scanf(“%d %d %d”, &a[i][0], &a[i][1] , &a[i][2]); p=&a[0][0]; move(p); printf(“Now,matrix:n”); for(i=0;i<3;i++) printf(“%d %d %d”,&a[i][0], &a[i][1], &a[i][2]); } move(int *pointer){ int i, j, t; for(i=0;i<3;i++) for(j=i;j<3;j++) { t= *(pointer+ 3*i + j); *(pointer+ 3*i +j)= *(pointer+ 3*j + i); *(pointer+3*j + i)=t; } }习题10.16 输入一个字符串,内有数字和非数字字符,如: a123x456 17960?302tab5876 将其中连续的数字作为一个整数,依次存放到一数组a中。例如123放在a[0]中,456放在a[1]中……统计共有多少个整数,并输出这些数。#include int i, j, k, m, e10, digit, ndigit, a[10], *pa; printf(“Input a string:n”); gets(str); printf(“n”); pstr=&str[0]; pa=&a[0]; ndigit = 0;i = 0;j=0; while(*(pstr+i)!=„ ‟) { if((*(pstr+i)>=„0‟)&&(*(pstr+i)<=„9‟))j++; else { if(j>0) { digit = *(pstr+i-1)-48; k=1; while(k { e10=1; for(m=1;m<=k;m++)e10 =e10*10; digit =digit+(*(pstr+i-k)-48)*e10; k++; } *pa=digit;ndigit++; pa++; j=0; } } i++; } printf(“There are %d numbers in this line.They are:n”,ndigit); j=0; pa=&a[0]; for(j=0;j printf(“%d”, *(pa+j)); printf(“n”);} 步骤三 课堂小结 本课主要讲了一些习题,希望通过这些例子加深对指针的了解,看到指针在程序设计中的重要应用。同学们课后需要多看、多想、多练,逐步去体会指针这一重要的概念。步骤四 布置作业 课后作业:第十章课后练习10.10、10.11 C语言程序设计实验十——指针 【实验1】 实验题目: 1、下列代码片段哪里有错误? char var1,ptr1; var1 = „x‟; ptr1 = &var1; 2、设有如下定义: Double var1, *ptr1, *ptr2; Float* ptr3; Int var2, *var4; 那么,var1, *ptr1, ptr2,*ptr2,ptr3,* ptr3,var2, var4,*var4个属于哪种数据类型? 3、下列代码片段在哪里有错误? Char c = ‟ A ‟; Char * p; p = c;或*p=‟A‟; 4、下列代码片段的输出结果是什么? charvar1 = „ S „; charvar2 = „ X ‟; char*ptr1, *ptr2; ptr1 = &var1; ptr2 = &var2; *ptr2 = *ptr1; printf(“%ct%cn”, *ptr1, var2); 【实验2】 实验题目:输入3个整数,按由小到大的顺序输出。 【实验3】 实验题目:输入10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换。 实验要求:写3个函数:(1)输入10个数;(2)进行处理;(3)输出10个数。 【实验4】输入年和天数,输出对应的年、月、日。 例如:输入2000和61,输出2000-3-1。 要求:都用指针实现。 《c语言程序设计新视角》第六章 指针小结 指针特殊存地址,变量运算受限的。指针类型要注意,不一定是整型的。想要存取单元值,先定地址是哪的。指针若要移一下,步长类型确定的。 C语言程序设计实验七:函数、数组、指针 1、程序运行后,用户任意输入一个字符串,求出字符串长度,然后输出字符串内容及个 数。不能使用strlen函数。 求字符串长度函数的函数原型必须如下: int MyStrLenPt(char *str) 若输入:nihao123! 则输出:nihao123!:9 chars2、编写一个对一维数组进行排序的程序。 要求: 写两个函数,一个主函数,一个sort函数。在主函数中完成数组的输入和输出,通过调 用sort函数对数组进行排序。 sort函数的原型为:voidsort(int*p, intn); 说明: (1)请大家按学号来坐,便于考勤和管理。 (2)请珍惜宝贵的实验时间!不要做与实验无关的事情,比如聊QQ、上网或打游戏。 (3)直接把C语言代码粘贴到相应的实验题目下方,上交实验报告时只交word文档。 (4)文档名称:班级+学号后2位+姓名+实验编号,例如11电1班12张山实验七.doc。 C语言程序设计教案 C语言程序设计教案 C 语言程序设计教案 C 语言概述 【教学目的】 1)了解 C 的发展 教学目的】 2)熟悉 C 的特点 教学重点】 【教学重点】 C 语言的特点 难点)(难点)教学方法】 【教学方法】 例举法,推导法,归纳法 课时计划】 【课时计划】2 课时 【授课时间】2005-11-1 授课时间】 教学过程】 【教学过程】 导 言 程序的目的是处理数据,所以设计程序首先的知道这门语言可以处理什么样的数据 新课内容 一,C 语言的历史及其特征 二,简单 C 语言的程序实例 # include “stdio.h” main(){int a,b,sum;printf(“enter two numbers:”);scanf(“%d%d”,&a,&b);sum=a+b+6;printf(“%d”,sum);} 三,编辑,编译,连接,运行一个 C 语言程序 四,C 语言的特点 课堂练习】 【课堂练习】 1.C 语言规定,必须以()作为主函数名..A.stdio B.function C.include D.main 2.C 程序的基本构成单位是().A.子程序 B.函数 C.过程 D.函数和过程 函数和过程 【小 结】 总结:C 语言特点 课后作业】 【课后作业】7 页 2 【板书设计 板书设计】 板书设计 一,C 语言的历史及其特征 二,简单 C 语言的程序实例 # include “stdio.h” main()1 C 语言程序设计教案 {int a,b,sum;printf(“enter two numbers:”);scanf(“%d%d”,&a,&b);sum=a+b+6;printf(“%d”,sum);} 三,编辑,编译,连接,运行一个 C 语言程序 四,C 语言的特点 教学后记】 【教学后记】 学生听课认真,积极回答老师提出的问题.课堂教学效果很好,能够按时完成课堂练习题.对软件开发这个专业很有信心.2 C 语言程序设计教案 数 据 类 型 【教学目的】 1)常量.变量概念简要介绍 教学目的】 2)详细介绍,三种类型的常量.变量的使用规则,占内存大小及范围 教学重点】 【教学重点】 变量的使用 教学难点】 【教学难点】 变量占内存空间大小 授课时间】 【授课时间】2005-11-2 课时计划】 【课时计划】2 课时 【教学方法】举例法 教学方法】 方法 教学过程】 【教学过程】 导 言 程序 = 数据结构 + 算法 + 程设方法 + 语言工具 新课内容 一, 数据类型分类 1.基本类型 2.构选类型 3.指针类型 4.空类型 二, 常量,变量 1, 常量,符号常量(1)定义:其值不改变(2)分类 a.整型: 2,0,-1 b.实型: 2.2 ,-3.4 c.字符: 'a','c' 2,变量(1)定义:值可以改变(2)组成因素 int a=20;变量名:a 变量值:20(3)标识符 a.定义:标识符,变量名,函数名,数组名等;b.规则: 已字母下划线打头 c.长度:ANSIC 不限 TURBOC 限 32 个字符(4)使用:先定义后使用 三, 数据 1,整型数据 3 C 语言程序设计教案.整型常量表示方法 a.十进制 123 ,-123 b.八进制 o35,o27 c.十六进制 oxA3,ox12.整型变量 a.形式: 2 进制 a.分类: int 2b short int 2b long int 4b b.定义 int a, b unsigned int c,d;long e, f,.整型,常量类型 2, 实型数据.表示方法 123, 123.0 ,0.0.实型变量 float 4b double 8b long double 16b double 类型.类型 float a;double b;b=1234.789 a=123456.789 3,字符数据.字符常量.一般字符 例子:“b”,“c”,“1”,'!'.特殊字符常量 说明: 以 开头的 :.字符变量.定义 char c1, c2;c1='A';c2='b'.举例 输出: a,A 4 C 语言程序设计教案 97,65.字符串变量 1.定义:例 “123”“A” , 2.以字符' ' 结束标志.变量赋值 1.定义变量 同时赋值 例: int a=978;float=b=98.67;char=c='c';2.定义变量 一部分赋值 例: int a,b,c=91;3.几个变量 同时赋值 例: int a=b=c=d=97;课堂练习】 【课堂练习】 1, main(){float a, b;a=123456.789e+6;b=a+30 printf(“%f”,b)} 2, main(){ char c1, c2;c1=97;c2=65;printf(“%c,%cn”,c1,c2);printf(“%d,%c/n”,c1,c2);【课后作业】 26 页 3,9,10 课后作业】 作业 , , 【小 结】 注意特殊字符常量,符号常量,变量在内存的存储形式 【板书设计】 板书设计】 一, 数据类型分类 二, 常量,变量 1, 常量,符号常量 2, 变量 三, 数据 1,整型数据 2, 实型数据 3,字符数据 5 C 语言程序设计教案.字符串变量.变量赋值 【教学后记】 教学后记】 后记 本次课内容充实,知识点多,所讲内容,学生都能听懂,但运用不够熟练,需要多做练习, 以巩固加深.6 C 语言程序设计教案 运 算 符 与 表 达 式 【教学目的】 1.了解理解运算符 教学目的】 2.运用算术运算符及使用 授课重点】 【授课重点】 表达式的使用 授课难点】 【授课难点】 I++与++I 的区别 教学方法】 【教学方法】 举例法,分析法 授课时间】 【授课时间】 2005-11-3 课时计划】 【课时计划】 2 课时 【教学过程】 教学过程】 导 言 运算量+ 运算量 1 + 2 新课内容 一 各数值数据的混合运算 1.总则: 自动转换同类型 2.规则:.(1)float->double char,shor->int(2)可直/间转换 int->ussigned->long->double 二 算术运算符,表达式 1.运算符(1)算术(2)位 &!~ ^(3)条件 ? :(4)指针 & * 2.算术运算符,表达式(1)基本算术运算符 + — * /(2)运算符优先级 a.* /-> + b.同级,运算符结合 c.强制类型转换 形式:(类型名)(表达式)例子: main(){ float x;int y;x=8.56;7 C 语言程序设计教案 y=(int)x;printf(“x=%f,y=%d”,x,y);d.自增,自减运算 I++=>1)I, 2)I=I+1;++I=>1)I=I+1, 2)I 三,数据输入和数据输出 a)数据输出: 命令格式:printf(控制字符串,参数 1,参数 2,……)例如:main(){float x=1234.565;int y=234;char c='a';printf(“%f,%d,%c”,x,y,c);} 数据输入: 命令个是:scanf(控制字符串,参数 1,参数 2,……)例如:main(){float x int y;char c;scanf(“%f,%d,%c”,x,y,c);} 课堂练习】 【课堂练习】 分析程序的输出结果: main(){ int i=2;i+=i-=i+i;printf(“%dn”,i);} 【小 结】 数据类型必须掌握整型,浮点型,字符型,还要掌握各种运算符之间的区别与联系.课后总结】 【课后总结】 提纲 一,各种数据数据类型自动转换规则 二,算术运算符及表达式 1,自增 i++与++i 区别 , 1, 运算符优先级结合性 b)8 C 语言程序设计教案 2, 强制类型转换运算符 课后作业】 【课后作业】26 页 3 教学后记】 【教学后记】 学生听课认真,没有人开小差.能跟上老师的思路,积极思考问题.所讲内容都能听懂, 但个别容易出错的地方还有待加强.9 C 语言程序设计教案 顺序结构(数据的输入和输出)顺序结构(数据的输入和输出)【教学目的】 使学生明白现实世界程序的顺序处理 教学目的】 教学重点】 【教学重点】 理解顺序结构 教学难点】 【教学难点】 变量占内存空间大小 教学方法】 【教学方法】 讲授课 教学日期】 【教学日期】 2005-11-7 课时计划】 【课时计划】 2 课时 【教学过程】 教学过程】 导 言: 举例引出程序思想 新课内容: 一, 基本结构 1.顺序结构 A->B 2.选择结构 A->B 或 A->C 之中选择 3.循环结构 WHILE()~~ DO ~~WHILE()二, 数据输入输出语句 1.输入输出:用函数实现 2.使用库函数 “I#INCLUDE” 3.常用函数(I/0)(1)字符数据的 I/0 A.putchar(c)字符输出 putchar('')putchar('r')B.getchra()字符输入(2)格式输入/输出 A.printf(格式控制,输出列表)(1)%d 十进制 例:int I=123;printf(“%d”,I)123 printf(“%2d,%4d”,I,I)(2)%0 八进制 例:int I=-2;printf(“%d,%0”,I,I);(3)%x 十六进制 ffff(4)%u 输出无符号整型 123, 123 I=-2 I=177776 10 C 语言程序设计教案 unsigned ing a=65535(5)%c 输出一个字符 printf(“%c”,c)printf(“%d”,c);(6)%s 输出字符串 printf(“%s”,“hello”);printf(“%s”,“you are goods”)(7)%f 输出实数 float I,j printf(“%f”,11111.1111+33333.3333)(8)%e 指数输出 int I I=123.456;Printf(“%e”,I)l.234560e+002 B scanf 输入函数(1)形式:scanf(格式控制,地址列表)(2)例子: int I scanf(“%d”,&I);请你输入整性数据 44444.4444 三,C 语句 1.控制语句(1)if()~~else 条件语句(2)for()~~~循环语句(3)while()~~循环语句(4)do~while()循环语句(5)cotinue 循环语句(6)break 终止语句(7)switch 分支语句(8)goto 转向语句(9)return 返回语句 2.函数调用 printf()scanf()3.表达式语句 4.空语句;5.复合语句 {} 课堂练习】 【课堂练习】 1.输入三角形边求三角形的面积 2.从键盘输入一小写字符转化成大写字符 11 C 语言程序设计教案 【小 3.求: ax+bx+c=0 的根 结】 一,各种数据数据类型自动转换规则 二,算术运算符及表达式 1,自增 i++与++i 区别 , 3, 运算符优先级结合性 4, 强制类型转换运算符 课后作业】 【课后作业】34 页 10,11,12 , , 【教学后记】 教学后记】 上课纪律很好,所有学生都能认真听课.所讲知识都能听懂,练习能按时完成且正确率高.对于自加,自减的综合运用,还有些学生容易出错.下次课再强调一下.12 C 语言程序设计教案 语句)分 支 结 构(if switch 语句)【教学目的】 1)使学生能熟练运用简单的语句进行顺序结构程序设计 教学目的】 2)运用单分支条件语句进行判定结构程序设计 3)运用双分支条件语句进行判定结构程序设计 4)运用多分支条件语句进行判定结构程序设计 教学重点】 【教学重点】 条件语句的应用 教学难点】 【教学难点】 条件语句的熟练使用 教学方法】 【教学方法】 讲授课 【教学日期】 2005-11-8 教学日期】 时计划】 【课时计划】 4 课时 教学过程】 【教学过程】 导 言: 我们利用简单语句可以进行程序设计, 但只是简单程序设计.在设计程序时经常会遇到根 据某些情况进行选择操作,这样就得用判断语句.新课内容: 一,语句的分类 1.表达式语句 2.空语句 3.复合语句 4.函数调用语句 5.控制语句 二,if 语句 1.If 语句的一般形式 命令格式:if(条件)语句 1 [else 语句 2] 例如:#include“stdio.h” main(){int a,b,s1,s2;printf(“请输入两个整数 a,b:”);scanf(“%d,%d”,&a,&b);s1=a+b;s2=a*b;if(s1>s2)printf(“a 与 b 的和大于 a 与 b 的积”);else printf(“a 与 b 的积大于等于 a 与 b 的和”);} 2.If 语句中的复合语句 13 C 语言程序设计教案 如果两个分支中需要执行的语句不止一条,必须用“{}”括起来.例如:#include“stdio.h” main(){float a,b,u,v,s,r;printf(“请输入两个整数 a,b:”);scanf(“%d,%d”,&a,&b);if(s1>s2){r=a*a-b*b;s=a/b;} else {r=b*b-a*a;s=a/b+4;} u=(r+s)*(r+s);v=u*(r+s);printf(“u=%f,v=%f”,u,v);} 3.较复杂的条件表达式 4.If 语句的嵌套 了解 if 语句的嵌套规则 例如:输入 a, b 两个数,比较并输出结果.Main(){int a,b;printf(“please input two integer”;)scanf(“%d,%d” ,&a, &b);if(a)b)printf(“a)b”;)else if(a=0;I--)printf(“%d”,a[I]);} 例 2:从键盘输入字符,记下“a”到“z”这些小写字母出现的次数,当输入!号 时结束输入.Main(){int I,a[26];char ch;for(I=0;I<26;I++)a[I]=0;while(ch!='!')22 C 语言程序设计教案 {scanf(“%c”,&ch);if(ch>='a'&&ch<='z')a[I]=a[ch-97]+1;} for(I=0;I<26;I++)printf(“%d,a[I])} 四,二维数组的定义 类型名 数组名[常量表达式 1] [常量表达式 2] 特点:可以定义多个分量,但这些分量只能存储同一个类型的数据.五,数组分量的引用 例如:int a[3] [4]-----定义一个有 12 个分量的数组 我们可以把他们看成三个一维数组,数组名分别为 a[0] a[1] a[2]分量的引用 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][0] a[2][0] a[2][0] 六,二维数组的应用 建立一个 3*4 的矩阵,初始值来源于键盘的输入,并且输出 课堂练习】 【课堂练习】输入一个有序序列,在输入一个新数,将此数插入在此序列中.【小 结】一维数组,二维数组的定义 一维数组的分量引用,二维数组的分量的引用 一维数组和二维数组的应用 课后作业】 【课后作业】84 页 1 教学后记】 【教学后记】 一维数组的应用学生能理解,且应用得较好.二维数一开始在理解上有些困难,通过在黑 板上演示程序的执行过程,学生掌握了二维数组的内容.涉及较复杂,抽象内容最好的方法是 以直观的方式给学生展示,这样便于学生理解和掌握.23 C 语言程序设计教案 字符数组与字符串 【教学目的】 1)理解字符数组的定义.教学目的】 2)掌握数组定义的格式及数组的应用方法 3)综合运用数组.教学重点】 【教学重点】综合运用字符数组.教学难点】 【教学难点】综合运用字符数组.教学日期】 【教学日期】2005-11-22 【课程类型】 讲授课 课程类型】 课时计划】 【课时计划】 4 课时 教学过程】 【教学过程】 导 言:我们应用每一个变量都的一一定义如果想一次定已多个变量这时就的使用数组.新课内容: 一,字符数组类型的定义 char 数组名[常量表达式] 特点:可以定义多个分量,但这些分量只能存储一个字符.二,字符数组的初始化: 1,static char c[10]={'I',' ' 'a',' 'm ','h' 'a ''p' 'p ''y' };把 10 个字符分别付给 c[0]到 c[9]的 10 个元素 三,字符数组的引用 例 1:输出一个字符串 例 2:输出水晶石 四,字符串 1, 字符串和字符串结束标志 2, 用字符串常量给字符串初始化 3, 通过赋初值隐含确定数组长度 4, 字符串的输入输出 5, 字符串处理函数 四,字符数组的应用: 某单位的工作证号码的最后一位是用来表示性别的, 如 f 表示男,m 表示女,今输 入 10 个人的工作证号码,请统计出其中的男女人数 课堂练习】 【课堂练习】84 页 6,7 , 【小 结】字符数组,字符串的定义及两者之间的关系 字符数组的应用 课后作业】 【课后作业】84 页 3,8 , 教学后记】 【教学后记】 字符数组的定义和应用学生能很快理解并掌握.24 C 语言程序设计教案 指 针 【教学目的】 1)掌握指针的定义 教学目的】 2)掌握指针的引用方式 3)掌握字符指针与字符串指针之间的关系 教学重点】 【教学重点】指针的概念,指针的正确引用 教学难点】 【教学难点】指针的正确引用 课程类型】 【课程类型】 讲授课 教学日期】 【教学日期】 2005-11-24 【课时计划】 2 课时 课时计划】 教学过程】 【教学过程】 导言:指针是 c 语言中重要的数据类型,是 c 语言的精华,灵活的运用指针可以处理 各种复杂的数据结构,可以使程序简洁,紧凑,高效.一,指针的定义与引用 1,指针的概念:就是专门又来存放某种变量的地址 2,指针变量的定义:格式:类型表示符 *标识符 int i, j;int *p1,*p2;p1=&i;p2=&j;1, 指针变量的引用: 例:输入两个整数,按先大后小的的顺序输出 main(){int *p1,*p2,*p,a,b;scanf(”%d,%d“,&a,&b);p1=&a;p2=&b;if(a 第二篇:C语言程序设计实验十指针
第三篇:《c语言程序设计新视角》第六章指针小结
第四篇:C语言程序设计实验七:函数、数组、指针
第五篇:C语言程序设计教案