C语言教材第七章
C语言程序设计课件 第七章

7.4 数组和指针
3. 二维数组元素的地址 二维数组元素的地址也可以通过每行的首地址来表示。 a[0]、a[1]、a[2]是三个一维数组的名字,表示各 行 的 首 地 址 , a[0] 是 第 0 行 第 0 个 元 素 的 地 址 , a[0]+1第0行第1个元素的地址,... a[1] 是第1行 第0个元素的地址,a[1]+1第1行第1个元素的地 址,... a[i]的移动以元素为单位。 实 例 中 , &a[0][0] 可 用 a[0]+0 表 示 , &a[0][1] 可 用 a[0]+1表示 二维数组元素a[i][j]的地址可以用以下五种表达式求 得: &a[i][j] a[i]+j *(a+i)+j &a[0][0]+4*i+j a[0]+4*i+j
7.3函数与指针
形式: 类型名 函数名(类型名 形参1,类型名 形参2…) /* 头部 */ { 说明部分 /* 函数体*/ 语句部分 }
7.3函数与指针
7.3.1 指针作函数参数
若函数的形参为指针类型,调用该函数时,对应实参必须是基类 型相同的地址值或已指向某个存储单元的指针变量。虽然实 参和形参之间还是值传递方式,但由于传递的是地址值,所 以形参和实参指到了同一个存储单元,函数中,通过形参操 作的存储单元,与实参所指是同一单元,因此实参的值发生 了改变。利用此形式,可以把两个或两个以上的数据从被调 用函数中返回到调用函数。 当需要通过函数改变变量值时,使用指针作函数参数。
7.2 指针的定义、使用和运算
7.2.3 指针变量的初始化
指针变量在定义时可以用任何合法的指针(地址)值进行初始化。 如果在定义指针变量时没有进行初始化,全局变量和局部静态变 量将被自动地初始化为空指针(0)。局部自动变量、寄存 器变量将不自动初始化,这些变量建立后的值不能确定。一 定要有明确的变量关联后,才能使用这些变量。
c语言第七章

/* 定义a、b和sum三个变量 */
a=3; b=4;
/* 为a,b赋值 */
sum=add(a,b);
/* 调用函数add,将得到的值赋给变量sum */
printf("sum=a+b=%d\n",sum); /* 屏幕输出sum变量的值 */
} int add(int x,int y) /* 定义add函数和形式参数 x,y */
全局变量说明 宏定义: #define PI 3.14159。
函数模块定义 ……
条件编译:#if…#else…#endif
函数模块定义 函数预说明:定义函数的原型
全局变量说明:函数外定义的变量
函数模块定义
2021/4/6
《C语言程序设计》-第七章
7
7.2 函数的定义、参数 及函数的值
7.2.1 函数定义的一般形式 7.2.2 函数的参数 7.2.3 函数的返回值
}
2021/4/6
《C语言程序设计》-第七章
18
/*63【 例1.1 】 C语言程序的函数应用*/
int add(int ,int );/*函数声明*/
main( )
/* 主函数 */
{
int a,b,sum;
a=3; b=4;
sum=add(a,b); /* 调用函数add,将得到的值赋给变量sum */
2021/4/6
《C语言程序设计》-第七章
24
7.4.3函数的递归调用
▪递归调用(自调 用函数)
在调用一个函数的过 程中,又出现直接或间 接地调用该函数本身。
2021/4/6
《C语言程序设计》-第七章
25
/*67谭例8.7*/
C语言教材第七章指针实验

C语⾔教材第七章指针实验第七章指针第⼀部分知识训练【知识要点】1. 地址与指针指针变量的概念:⽤⼀个变量专门来存放另⼀个变量的地址。
2. 指向变量的指针变量指针变量的形式:基类型 *指针变量名;&: 取地址运算符;*:指针运算符。
3. 指针与数组引⽤⼀个数组元素可以⽤下标法和指针法;可以⽤数组名作函数的参数。
4.指针与函数函数指针变量定义的⼀般形式为:类型说明符 (*指针变量名)();⼀个函数的返回值可以是⼀个函数。
【典型习题与解析】5. char * const p;char const * pconst char *p上述三个有什么区别?【解析】char * const p; //常量指针,p的值不可以修改;char const * p;//指向常量的指针,指向的常量值不可以改;const char *p; //和char const *p。
6. main(){int a[5]={1,2,3,4,5};int *ptr=(int *)(&a+1);printf("%d,%d",*(a+1),*(ptr-1));}输出结果是什么?【解析】答案:输出:2,5*(a+1)就是a[1],*(ptr-1)就是a[4],执⾏结果是2,5。
&a+1不是⾸地址+1,系统会认为加⼀个a数组的偏移,是偏移了⼀个数组的⼤⼩(本例是5个int)。
1)&a是数组指针,其类型为 int (*)[5];⽽指针加1要根据指针类型加上⼀定的值,不同类型的指针+1之后增加的⼤⼩不同。
2)a是长度为5的int数组指针,所以要加 5*sizeof(int),所以ptr实际是a[5],但是prt与(&a+1)类型是不⼀样的(这点很重要),所以prt-1只会减去sizeof(int*) a,&a的地址是⼀样的,但意思不⼀样。
3)a是数组⾸地址,也就是a[0]的地址,&a是对象(数组)⾸地址,a+1是数组下⼀元素的地址,即a[1],&a+1是下⼀个对象的地址,即a[5]。
C语言第7章_文件及应用

精选ppt课件
16
7.2.2 用于文件操作的函数
2.文件的读写函数
1)字符读写函数:
int fputc ( int ch, FILE *fp); int fgetc(FILE *fp);
2)串读写函数
int fputs(const char *str, FILE *fp); char *fgets(char *str,int length,FILE *fp);
cchh=agretachd(d);r[20];
} sitf;(ch=='e' || ch=='E' ) break;
}i;f ((fp=fopen("mail","w"))==NULL)
f{close(fp);}
printf("file open failed!!!\n");exit(精0)选; ppt课件
21
}
7.2.2 用于文件操作的函数 /* 功 能: 建立一个学生通讯录的数据库文件*/
/* 说 明: 使用块写入函数fwrite()*/
#m{ inawcinlhu(i)dlee(1【录")std。例io.7h."15】如例7.11,用块写函数来建立学生通讯
FIL{E p*rfipn;tf("姓名:"); scanf("%s",);
返回值为指向此文件的指针,以后使用。 如果打开失败,返回值为NULL。
精选ppt课件
15
7.2.2 用于文件操作的函数
1.文件的打开与关闭函数
2)关闭文件 函数fclose()关闭由fopen()函数打开的流。 fclose()函数把遗留在缓冲区的数据写入文 件,实施操作系统级的关闭操作。同时释 放与流联系的文件控制块。
C语言 第7章 多重循环

当 y10 <=10
循环变量y5赋初值y5=0 当 y5 <=20
y20*20+y10*10+ y5*5==100?
True
False
输出y20,y10,y5 的组合
y5++ y10++ y20++
例7.3代码
C语言案例教程
main( ) {
int a, b, c; for ( a=0;a<=5; a++) {
7.3 多重循环举例 C语言案例教程
• 【例7.3】银行换零钱。假定你拿1张百元钞票到银行换
零,要求是必须换成若干张20元、10元和5元。请编写程
序,找出所有可能的找零组合,如1张20元,5张10元,6
张5元。
定义循环变量y20,y10,y5
循环变量y20赋初值y20=0
当 y20 <= 5 循环变量y10赋初值y10=0
1 12 123 1234 12345 ……
循环变量x赋初值x=2
当 x <= n
先假设x是素数:flag=1
循环变量y赋初值y=2
当 y<x
True
x%y==0? False
flag=0 True
y++ flag==1?
False
输出x x++
• main()
•{
•
int x, y,n,flag;
•
scanf("%d", &n);
•
for ( x=2; x<=n; x++)
• 编程点拨:
– 首先要对2到n间的每个数进行一下判断,如果是素数,则输出,否则继续判断 下一个数。可以用一个循环来控制数从2变化到n(取循环变量为x)。
C语言(第七章)—清华大学出版社

实参表求值顺序,因系统而定。
例 求一个整数的立方
14
int cube (int x) /* 函数定义 */ { return (x * x * x); }
9
{ if{v{nootrii说(,difj;o=明函r1语(数;j i=句名<1=(;类nj ;<型i=+1+n)-参i; j数++1) ,类//**型需输2要出参输每数出行2的左,…行边)数的/空**首/ 格部*/*/ 执行p语rin句tf(" ");
reftourr(nj =; 1/;*可j <以= i省; j+略+)retur/*n输语出句每*/行的数字 */
7.1 概述
4
源程序文件1
C程序 函数是指完成一 个特定工作的独 立…程序…模块。源程序文件n
函数1 … 函数n
函数1 … 函数m
使用 ① 程序结构清晰,可读性好。
函数 ② 减少重复编码的工作量。
的 好处
③ 可多人共同编制一个大程序,缩短程序
设计周期,提高程序设计和调试的效率。
5
说明
⑴ 一个C源程序可以由一个或多个源程序文件组成。 C编译系统在对C源程序进行编译时是以文件(.cpp)为 单位进行的。
}
printf(" %d ", i); /* 每个数字的前后各有一个空格 */
putchar ('\n');
表} 示不返回结果 } 不能省略,否则,函数类型被默认定义为int
c语言程序设计第7章(谭浩强)PPT版本
如 int a[5]; static int a[5]={6,2,3}; int a[]={1,2,3,4,5,6}; 等价于: a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0; 等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0; 如 编译系统根据初值个数确定数组维数 int a[3]={6,2,3,5,1}; ()
例
38 49 49 38 65 76 97 13 97 76 97 27 13 30 97 27 97 30 初 始 关 键 字 n=8
38 49 65 13 76 27 76 13 30 76 27 76 30 97 第 一 趟
38 49 13 65 27 65 13 30 65 27 65 30
程序举例
#include <stdio.h> #define SIZE 10 例 读10个整数存入数组,找出其中最大值和最小值 main() { int x[SIZE],i,max,min; printf("Enter 10 integers:\n"); for(i=0;i<SIZE;i++) 步骤: { printf("%d:",i+1); 1. 输入:for循环输入10个整数 scanf("%d",&x[i]); 2. 处理: } (a) 先令max=min=x[0] max=min=x[0]; (b) 依次用x[i]和max,min比较(循环) for(i=1;i<SIZE;i++) 若max<x[i],令max=x[i]{ if(max<x[i]) max=x[i]; 若min>x[i],令min=x[i] if(min>x[i]) min=x[i]; 3. 输出:max和min } printf("Maximum value is %d\n",max); printf("Minimum value is %d\n",min); }
C语言(第七章数组)
对部分元素赋初值(前面的连续元素)。如: int b[10]={0,1,2,3,4};
表示数组元素的值为:
b[0]=0; b[1]=1; b[2]=2; b[3]=3; b[4]=4; 后5个元素的初值为0。
注意:不能只对不连续部分元素或后面的连续
元素赋初值。 语句: int a[10]={, , , , ,1,2,3,4,5};
main ( ) { int a[2] [3]={{1, 2,3},{4, 5,6}}; int b[3] [2], i, j; printf("array a: \n"); for (i=0; i<=1; i++) { for (j=0; j<=2; j++) { printf("%5d", a[i][j]); b[j][i]=a[i][j]; } printf("\n"); } printf("array b:\n"); for (i=0; i<=2; i++) { for (j=0; j<=1; j++) printf("%5d", b[i]j]); printf("\n"); } }
运行结果如下:
1
1
2
3
5
8
89
13
144
21
133
34
377
55
610
987
1597
1584
4181
6765
四、简单预处理指令
1. 指令格式:
#define 符号常量
2. 指令作用
文本串
用整型表达式替换程序中所有的符号常量。
C语言第7章_指针
退出
指针运算
算术运算 int *p, a[10]; p = a; p++; /*p的值增加多少?*/ 的值增加多少? 的值增加多少 指针的加减运算是以其指向的 指针的加减运算是以其指向的 类型的字节长度为单位的 类型的字节长度为单位的
6000 6001 6002 6003 6004 6005 6006
swap函数的几种错误形式(3/3) 函数的几种错误形式 3/3)
指针p没有确切地址 指针 没有确切地址 void Swap(int *p1, int *p2) { int *p; /*指针 未初始化*/ /*指针p未初始化*/ 指针p未初始化 *p = *p1; *p1 = *p2; *p2 = *p; }
退出
寻址方式
如何读写内存中的数据? 如何读写内存中的数据? 两种寻址方式 直接(寻址)访问 直接(寻址)
通过变量地址直接存取变量内容
0 ┇ 3 6 9 ┇ 3010 2000 变量 i_pointer 变量 i 变量 j 变量 k 内存用户数据区
通过变量的地址访问变量所在的 2000 存储单元
2002 2004
退出
指针运算
赋值运算 指针在使用前一定要赋值 为指针变量赋的值必须是一个地址 main() { int *p; scanf("%d",p); … }
错! 但TC下不报错 下不报错 VC下报错 下报错
main() { int a,*p=&a; scanf("%d",p); … }
退出
指针与函数
指针既然是数据类型,自然可以做函数参数和返回值 指针既然是数据类型, 的类型 指针做函数参数的经典例子: 指针做函数参数的经典例子:
C语言程序设计教程第7章
C语言程序设计教程第7章《C语言程序设计教程》第7章是关于数组和指针的内容。
本章从数组的定义、初始化、访问等基础知识开始讲解,然后介绍了二维数组、多维数组和字符数组,并通过具体的示例代码进行讲解。
此外,本章还讲解了指针的概念和用法,包括指针的定义、指针的运算、指针与数组的关系等内容。
首先,本章介绍了数组的定义和初始化的方法。
数组是由相同类型的数据元素组成的有序集合,使用方括号来定义数组的长度。
数组可以通过下标来访问和修改元素的值。
此外,本章还介绍了数组初始化的方法,包括静态初始化和动态初始化。
然后,本章详细讲解了二维数组和多维数组的概念和使用方法。
二维数组可以看作是由多个一维数组组成的,可以通过两个下标来访问和修改元素的值。
多维数组与二维数组类似,只是多维数组可以有更高维度的数组。
本章通过示例代码演示了如何定义和使用二维数组和多维数组。
接下来,本章介绍了字符数组的概念和使用方法。
字符数组是由字符组成的一维数组,可以用于存储和处理字符串。
本章通过示例代码演示了如何定义、初始化和使用字符数组,包括字符串的输入、输出和处理。
最后,本章详细讲解了指针的概念和用法。
指针是一种特殊的变量,可以存储变量的地址。
本章介绍了指针的定义和初始化的方法,以及指针的运算,包括指针的加法、减法和比较操作。
本章还讲解了指针与数组的关系,包括指针与一维数组的关系、二维数组的关系和字符数组的关系。
本章通过示例代码演示了指针的使用方法,包括指针与数组的遍历、指针与字符串的处理等。
总之,第7章《数组和指针》是《C语言程序设计教程》中比较重要和基础的章节。
通过学习本章的内容,读者可以了解数组和指针的概念和用法,掌握数组和指针的定义、初始化、访问等基本操作,以及掌握二维数组、多维数组和字符数组的使用方法。
通过本章的学习,读者可以更好地理解和运用C语言的数组和指针特性,提高自己的编程技能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2016/7/31 2/78
数学中的函数
y f ( x)
因变量 函数名 自变量
程序设计中的函数
程序设计中的函数不局限于计算
–计算类,如打印阶乘表的程序…… – 判断推理类,如排序、查找…… 2016/7/313来自78问题的提出
读多少行的程序能让你不头疼? 假如系统提供的函数printf()由10行代码替换, 那么你编过的程序会成什么样子?
【例7.1a】 计算整数n的阶乘n!
/* 函数功能: 用迭代法计算n! 形参表,函 返回值类型 函数入口参数: 函数名说明 整型变量n表示阶乘的阶数 函数的功能 数入口 函数返回值: 返回n!的值 */ long Fact(int n) /* 函数定义 */ 函数内部可以定义 { 只能自己使用的变 int i; 量,称内部变量 long result = 1; for (i=2; i<=n; i++) { 返回值作为函数 result *= i; 调用表达式的值 } return result; }
–此话音落不久,诸葛亮果然病故于五丈原。
“事无巨细”,“事必躬亲” –管理学的观点是极其排斥这种做法的,认为
工作必须分工,各司其职
5/78
– 其中的思想,在程序设计里也适用 2016/7/31
7.1分而治之与信息隐藏
分而治之( Divide and Conquer,Wirth, 1971 )
– 函数把较大的任务分解成若干个较小的任务,并
提炼出公用任务
信息隐藏(Information Hiding, Parnas, 1972)
–设计得当的函数可把具体操作细节对外界隐藏
起来,从而使整个程序结构清楚
–使用函数时,不用知道函数内部是如何运作的
,只按照我们的需要和它的参数形式调用它即可
2016/7/31 6/78
程序设计的艺术
算法设计艺术
2016/7/31
24/78
防御性程序设计(Defensive Programming)
【例7.3】计算整数n的阶乘n! 从防止输出错误的结果考虑,主函数应如何修改? –增加对函数返回值的检验,有错误运算结果应报错
2016/7/31
25/78
防御性程序设计(Defensive Programming)
2016/7/31
27/78
【例7.4】编写计算组合数的程序
函数复用
unsigned long p;
p = Fact( m) / Fact (k) * Fact (m-k) printf("p = %lu" \n", p);
2016/7/31
28/78
7.3.4函数设计的基本原则
要考虑的问题:
– main()稍微特殊一点点 – C程序的执行从main函数开始 – 调用其他函数后流程回到main函数 – 在main函数中结束整个程序运行
2016/7/31
10/78
7.2.1函数的分类
标准库函数 – ANSI/ISO C定义的标准库函数
符合标准的C语言编译器必须提供这些函数 函数的行为也要符合ANSI/ISO
第7章 函数
华南师范大学增城学院
计算机系
秦笛
2016/7/31 1/78
本章学习内容
函数定义、函数调用、函数原型、函数的参数 传递与返回值
递归函数和函数的递归调用
函数封装,函数复用,函数设计的基本原则, 程序的健壮性
变量的作用域与存储类型,全局变量、自动变 量、静态变量、寄存器变量
函数封装(Encapsulation)使得外界对函数的影 响仅限于入口参数,而函数对外界的影响仅限于一 个返回值和数组、指针类型的参数
7.3.3函数封装与防御性程序设计
传入负数实参 会怎样?
【例7.1】
会使循环条件一 开始就不成立, 导致循环未执行
Why?
2016/7/31 22/78
防御性程序设计(Defensive Programming)
2016/7/31
}
a 函数 ③ { ② b(); … ⑥ ⑤ return; }
b函数 {
… …
④
return; }
30/78
函数嵌套是指在一个用户函数的函数体中,又出 现了另外用户函数的调用。如函数a调用函数b, 函数b又调用函数
7.4
#include<stdio.h> void main() { long fac(int); long cmn(int,int); c等。 int m,n; printf("m,n="); scanf("%d,%d",&m,&n); printf("C(%d,%d)=%ld\n",m,n,cmn(m,n)); } long fac(int k) /* 定义求k!的函数 */ { int i; long t; for(i=1,t=1;i<=k;i++) t*=i; return(t); } long cmn(int m,int n) /* 定义求组合数的函数 */ { long res; res=fac(m)/(fac(n)*fac(m-n)); return(res); }
2016/7/31
7/78
7.2 函数(Function)的定义
函数是C语言中模块化编程的最小单位 – 可以把每个函数看作一个模块( Module ) 如把编程比做制造一台机器,函数就好比其 零部件 –可将这些“零部件”单独设计、调试、测试好
,用时拿出来装配,再总体调试。 –这些“零部件”可以是自己设计制造/别人设 计制造/现成的标准产品
类型 函数名(类型 参数1, 类型 参数2, ……)
{ 声明语句序列 可执行语句序列 return 表达式;
函数出口
2016/7/31
}
返回运算的结果
12/78
7.2.2函数的定义
参数表里的变量(叫形式参数, Formal Parameter)也是内部变量
类型 函数名(类型 参数1, 类型 参数2, ……)
1.函数原型和函数声明 ⑴ 函数原型 函数原型是是定义函数时函数体以外的那些内容。 一般形式: 函数类型 函数名(数据类型1 形参1,类型2 形参2,…,类 型n 形参n) 简化形式: 函数类型 函数名(数据类型1,数据类型2,…,数据类型n ) ⑵ 函数声明 函数声明是在主调函数的函数体说明部分描述被调函数 原型。 2.函数调用 函数调用是对已定义函数的具体应用。 一般形式: 函数名(实参表) 2016/7/31 21/78
– 而实际上一个printf()有上千行代码
main()中能放多少行代码? 如果所有代码都在main()中,怎么团队合作? 如果代码都在一个文件中,怎么团队合作?
4/78
2016/7/31
问题的提出
《三国演义》中有这样一段描写: –懿问曰:“孔明寝食及事之烦简若何?”使
者曰:“丞相夙兴夜寐,罚二十以上皆亲览焉 。所啖之食,日不过数升。”懿顾谓诸将曰: “孔明食少事烦,其能久乎?”
【例7.3】计算整数n的阶乘n! 函数返回值、型参、内部变量均改定义成无符号类 型,若传入负数的实参时Fact()会返回-1吗?
存在死代码的原因何在?
2016/7/31
26/78
防御性程序设计(Defensive Programming)
【例7.2】计算整数n的阶乘n!
如何修改程序去除冗余代码? 如何保证不会传入负数实参?
–程序的灵魂 –Donald E. Knuth,
“The Art of Computer Programming”, 清华大学出版社(英),国防工业出版社(中)
结构设计艺术
–程序的肉体 –模块化(Parnas, 1972)
结构化(Structural) 面向对象(Object-Oriented) 面向组件(Component-Oriented) 面向智能体(Agent-Oriented) ……
Larry
Moe
Curly
2016/7/31
8/78
7.2 函数(Function)的定义
若干相关的函数可以合并成一个“模块” 一个C程序由一个或多个源程序文件组成
一个源程序文件由一个或多个函数组成
2016/7/31
9/78
7.2.1函数的分类
函数生来都是平等的,互相独立的,没有 高低贵贱和从属之分
C的定义
– 第三方库函数
由其他厂商自行开发的C语言函数库 不在标准范围内,能扩充C语言的功能(图
形、网络、数据库等)
自定义函数 –自己定义的函数
包装后,也可成为函数库,供别人使用
11/78
2016/7/31
7.2.2函数的定义 (Function Definition)
返回值 类型 函数名标识符, 点明函数功能 参数表相当于 运算的操作数
2016/7/31 16/78
函数的参数传递
实参和形参必须匹配 –数目一致,类型一一对应(否则会发生自动类型转换)
7.1a将求阶 乘工作设计成 函数,在本例 中,编写主程 序,通过调用 阶乘函数时给 以不同的实参 值,实现求任 何阶乘。
一个任务可以定义有参 函数来完成,也可以定 义无参函数来完成,两 种会有什么不同
2016/7/31
【例7.1b】
P148
17/78
7.3.2函数原型(Function Prototype)