C语言程序设计第九章课件

合集下载

谭浩强 c语言程序设计(第九章)

谭浩强 c语言程序设计(第九章)
形式1: #ifdef 标识符 程序段1 #else 程序段2 #endif 意义:若该标识 符已被#define 命令定义,则编 译程序段1,否 则编译程序段2 形式2: #ifndef 标识符 程序段1 #else 程序段2 #endif 意义:若该标识
符没有被#define 命令定义,则编 译程序段1,否则 编译程序段2
4
第九章 预处理命令
例:下列程序宏替换。
例 #include <stdio.h> #define N 2 #define M N+1 # define NUM (M+3)*M/2 void main() { int i; for (i=0; i<=NUM; i++); printf(“%d\n”,i); }
第九章 预处理命令
第九章 预处理命令
内容提要: ★宏定义
★文件包含
★条件编译
1
第九章 预处理命令 – 作用:对源程序编译之前做一些处理,生成扩展C 源程序 种类
• 宏定义 • 文件包含 • 条件编译 #define #include #if--#else--#endif等
– 格式:
• “#”开头 • 占单独书写行 • 语句尾不加分号
#ifdef DEBUG printf(“x=%d,y=%d,z=%d\n”,x,y,z); #endif
#define DEBUG
字符串(可为空)
调试时:加上此命令 调试完成后:删去此命令
15
第九章 预处理命令 例5: (选择性地编译不同功能) 。根据需要,有时要把 字母全改为大写输出,另一些时候则要把字母全改为 小写输出。如何适应这两种不同要求。
11
第九章 预处理命令

江南大学C语言程序设计本科第九章ppt课件

江南大学C语言程序设计本科第九章ppt课件
<文件名> 表示在源文件所在目录以外的目录中查 找要 包含的文件
“文件名” 表示先在源文件所在目录中查找要包 含文件, 若没找到再在源文件所在目录以外的目录
f2.c
f1.c
f1.c
p2
#include “f2.c”
p2
p1 p1
使用文件包含指令时应注意几个问题: (1)一个#include指令只能包含一个文件,要包含多 个文件就要用多个#include指令

(4)被包含文件的扩展名一般用.h(头) ,表示是在文 件开头加进来的,其内容可以是程序文件或数据文 件,也可以是宏定义、全局变量声明等。这些数据 有相对的独立性,可被多个文件使用,不必在多个 文件中都去定义,而只在一个文件中定义,其他文 件中包含这个定义文件即可。
第三节 条件编译
形式1. # ifdef <标识符> { 程序段1} # else { 程序段1} # endif
结果:20
S(x+2,y+2) (y+2)*(x+2)
25.6
说明
1)替换时,可以是各种类型的量。 2)替换时不做计算。 3)可嵌套定义
#define PI 3.1415926 #define S(r) PI*r*r
第二节 文件包含处理
文件包含编译预处理命令格式: #include <文件名> 或 #include “文件名”
A v=14.0 B s1=31.5 C v=7.5ormat D s1=7.5ormat
s1=s(a+b); 〓s1=3.5*a+b*a+b=3.5*1+2*1+2=7.5 p(s1,f) 〓printf(“v=%format”,s1) 〓 printf(“v=%format”,s1)

C语言程序设计_课件_第九章(适于清华谭浩强版)

C语言程序设计_课件_第九章(适于清华谭浩强版)

注意, 注意,对嵌套结构体的引用必须引用
到最末一级。 到最末一级。
struct OBJECT { struct TASK { long plan; long start; long finish; } ti,tj; int count; } ob;
可以使用scanf(“%d”,&ob.ti.plan) 输 可以使用 入数据。但是不能引用ob.ti 。 入数据。但是不能引用
9.2 结构体与数组 9.2.1结构体包含数组 结构体包含数组 由于结构体的成员可以是任何基 本数据类型和另外一个构造类型, 本数据类型和另外一个构造类型,所 以结构体的成员当然可以是数组。 以结构体的成员当然可以是数组。 下面我们说明一个可以描述一个股票 信息的结构体: 信息的结构体:
struct STOCK { char stockname[8]; /*股票名称 */ 股票名称 char stockcode[6]; /*股票代码 */ 股票代码 float price[3]; /*买 入价、卖出价、成交价 */ 买 入价、卖出价、 }; ;
不能混淆结构体名和结构体变量这两 个概念。 个概念。结构体名实际上标识了程序员定 义的一种新的数据类型, 义的一种新的数据类型,编译系统不可能 为结构体名分配内存空间。 为结构体名分配内存空间。只有当变量被 说明为这种由程序员自己定义的数据类型 的结构体时, 的结构体时,编译系统才会为结构体变量 分配存储空间。在不引起混淆的情况下, 分配存储空间。在不引起混淆的情况下, 结构体变量可以简称为结构体。 结构体变量可以简称为结构体。
*/
Struct STOCK sfz={"ShenFaZhan","000001",8.77,8.78,8.78 }; /*用深发展的数据初始化结构体变量 用深发展的数据初始化结构体变量sfz*/ 用深发展的数据初始化结构体变量 printf("\n %s %s ", sfz.stockname, sfz .stockcode); /*输出股票名称和股票代码 */ 输出股票名称和股票代码 for (i=0;i<3;i++) /*输出股票的买入价、卖出价和成交价 输出股票的买入价、 输出股票的买入价 卖出价和成交价*/ printf("%6.2f ", sfz.price[i]); }

新编c程序设计第九章精选文档PPT课件

新编c程序设计第九章精选文档PPT课件
themegallery LOGO
2. 关于不带参数的宏定义的几点说明:
(1)宏名一般用大写字母表示,便于与变量名区别;一般将字符个数较多的 字符串用一个宏名替换,减少程序中多处引用字符串书写错误。
(2)宏定义是用宏名来表示一个字符串,在宏展开时以该字符串取代宏名, 这只是一种简单的代换, 预处理程序对它不作任何检查。如有错误,只能在编 译已被宏展开后的源程序时发现。
NUM宏展开: 2*N+1+1
再宏展开: 2*2+1+1
themegallery LOGO
4.带参宏定义
(1)带参宏定义格式:#define 宏名(形参表) 宏体 (2)带参宏调用格式:宏名(实参表) (3)宏展开:用宏调用提供的实参字符串,直接置换宏定义命 令行中相应形参字符串,非形参字符保持不变
可以引用已定义的 宏名,层层置换
printf(“ Input a radius: ");
scanf(“ %f", &r);
printf(“ length=%.2f,area=%.2f", L, AR);
printf(“ vo=%.2f\n", VO);
}
themegallery LOGO
3、无参宏的应用举例
themegallery LOGO
3、无参宏的应用举例
例 9.2在进行宏定义时,可以引用已定义的宏名。
#define PI 3.1415926
#define L PI*r*2 #define AR PI*r*r
在进行宏定义时,
#define VO main( ) { float r;
AR*r*4/3
main( ) { float r, s;

《C语言程序设计》电子课件 第9章课件

《C语言程序设计》电子课件 第9章课件

Your site here
重 庆
9.2文件的打开与关闭

子 工
3.使用文件的方式

文件使用方式
意义

(1)文件使用方式由r、w、a、t、 rt(只读)
打开一个文本文件,只允许读数据

b,+六个字符拼成,各字符的含义
学 院
是:r(read):读;w(write):写; a(append):追加;t(text):文本文
计 算
行管理,把它们的输入、输出等同于对磁盘文件的读和写。

ASCII文件:也称为文本文件,这种文件在磁盘中存放时每
学 院
个字符对应一个字节,用于存放对应的ASCII码。
二进制文件:是按二进制的编码方式来存放文件的。
Your site here

9.1文件概述



工 程
2.文件类型指针

用一个指针变量指向一个文件,这个指针称为文件指针。


9.1文件概述
9.2文件打开与关闭
计 算
9.3文件的读写

9.4文件检测函数


Your site here

第九章 文件



工 程
9.1概述
职 业
“文件”是指一组相关数据的有序集合。这个
学 院
数据集有一个名称,叫做文件名。实际上在前
面的各章中我们已经多次使用了文件,例如源
程序文件、目标文件、可执行文件、库文件



说明文件指针的一般形式如下:
FILE * 指针变量标识符

FILE *fp;

第9章C语言程序设计

第9章C语言程序设计

9.1位运算符
例9.2 按位或程序举例 main() { int a=9,b=5,c; c=a|b; printf("a=%d\nb=%d\nc=%d\n",a,b,c); } 运行结果:
9.1位运算符
9.1.3 按位异或运算
按位异或运算符“^”是双目运算符。其功能是参与运算的两数 各对应的二进位相异或,当两对应的二进位相异时,结果为1。参 与运算数仍以补码出现,例如9^5可写成算式如下: 00001001 ^00000101 00001100 (十进制为12) 9^5结果为12。按位异或通常用来: (1)与0异或,可以保留原值不变。如10^0 00001010 ^ 00000000 00001010
00001001 &00000101 00000001
按位与运算通常用来对某些位清0或保留某些位。例如即想让 某一个字节或多个字节中的位为0。例如:00001001(十进制9) 只要找到这样的数00000110、11110110、00000000等都可以, 即只要和要清零数中每一个二进制位相反即可,或者某一位二进制 位为0和0与结果也是0。
9.1位运算符
9.1.4求反运算
求反运算符~为单目运算符,具有右结合性。 其功能是对参与运算 的数的各二进位按位求反。例如~9的运算为: ~(0000000000001001)结果为:1111111111110110。
9.1位运算符
9.1.5 左移运算
左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算 数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数, 高位丢弃,低位补0。例如: a<<2 指把a的各二进位向左移动2位。 如a=2,十进制00000010,左移2位后为00001000 (十进制8)。 高位左移,低位补0。并且左移一位相当于乘以2的运算,左移两位 相当于乘以4即22。 例9.4 左移程序举例 main() { int a=2; a=a<<2; printf(“a=%d\n”,a); } 运算结果:

谭浩强C程序设计(第三版)清华课件第9章_预处理

谭浩强C程序设计(第三版)清华课件第9章_预处理


16、提出一个问题往往比解决一个更 重要。 因为解 决问题 也许仅 是一个 数学上 或实验 上的技 能而已 ,而提 出新的 问题, 却需要 有创造 性的想 像力, 而且标 志着科 学的真 正进步 。2021/6/29202 1/6/29J une

17、儿童是中心,教育的措施便围绕 他们而 组织起 来。202 1/6/292 021/6/2 92021/6/29202 1/6/29
printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v); }
8
运行情况如下:
input radius: 4↙
说明:
1=25.1328 s=50.2655 v=150.7966
(1) 宏名Biblioteka 般习惯用大写字母表示,以便与变量名相 区别。但这并非规定,也可用小写字母。
• 经过预处理后程序可由编译程序对预处理后的 源程序进行通常的编译处理,得到可供执行的 目标代码。
4
基本概念
• C语言与其他高级语言的一个重要区别是可以 使用预处理命令和具有预处理的功能。
C提供的预处理功能主要有以下三种:
1.宏定义
2.文件包含
3.条件编译
这些功能分别用宏定义命令、文件包含命令 、条件编译命令来实现。为了与一般C语句相 区别,这些命令以符号“#”开头。例如: #define #include
• 这个标识符(名字)称为“宏名”。
• 在预编译时将宏名替换成字符串的过程称为“宏展 开”。#define是宏定义命令。
6

9、要学生做的事,教职员躬亲共做; 要学生 学的知 识,教 职员躬 亲共学 ;要学 生守的 规则, 教职员 躬亲共 守。20 21/6/29 2021/6/29Tues day , June 29, 2021

C语言程序设计活页式教程 课件 项目9

C语言程序设计活页式教程   课件    项目9
如果一个数组中的所有元素保存的都是指针 , 那么就称它为指针数组 。指针数组的 定义形式一般为: 类型 *数组名[数组长度] ;
任务2 指针访问数组
【任务准备】 4. 二维数组的行指针 (1)指向二维数组的一般指针变量
在项目 6 中讲解过二维数组,二维数组有行和列,例如: short arr [2][3]= {{12,3,0}, {23,0,0}} ; (2)指向二维数组的行指针变量
任务3 指针访问字符串和函数
【任务实现】 训练 1 :从终端输入密码 ,编写一个密码检测程序 ,要求输出如下信息 ************************ 请输入密码: shdwa1234 密码位数错! ************************ 请输入密码: pwd_43 密码错! ************************ 请输入密码: pwd_ 12 密码正确 ,欢迎!
任务1 指针访问变量
【任务实现】 训练 1:食品店有鲜牛奶 、酸奶 、鲜榨果汁等商品 ,可提供“每月优惠订购 , 每日 送货到家 ”服务, 小红订购了一种商品 , 快递员在小红家安装了一个收件箱 , 每日按 时送货 。用函数调用的方法来模 拟一下这个收发商品的过程吧 。编程实现 , 要求输出 如下信息。 (1)训练分析
任务1 指针访问变量
【任务准备】 (3)直接访问与间接访问 变量的访问方式有两种: 直接访问和间接访问。 直接访问:按变量地址存取变量值(内容)的方式称为直接访问 ,如图 所示。 间接访问: 如果变量的地址存储在另一个变量的存储单元中, 如图 所示 , 变量 a 的地址存储在变量 p 的存储单元中 , 此时 , 需要先访问变量 p ,取得变量 p 的值(变量 a 的地址) ,通过该地址再存取变量 a 的值 ,这种方式称为间接访问。

C语言程序设计——指针(完整版)PPT教学课件

C语言程序设计——指针(完整版)PPT教学课件

说明:
(1)设有指向整型变量的指针变量p,若要把整型变量a 的地址赋予p,有以下方式: 指针变量初始化的方法: int a; int *p=&a; 赋值语句的方法: int a,*p; p=&a; (2)指针运算符*和指针变量说明中的指针说明符*不是 一回事。后者表示其后的变量是指针类型,前者则是一 个运算符用以表示指针变量所指的变量。
三、 指针变量作函数参数 C语言是通过传值将参数传递给函数的,对被调函数来说, 没有直接的方法来改变主调函数内的变量的值。 例:对两个整数按大小顺序输出。 #include<stdio.h> swap(int x,int y) {int t; t=x; x=y; y=t; } void main( ) {int a=3,b=5; if(a<b) swap(a,b); printf(“a=%d,b=%d \n”,a,b); }
说明:
(1)指针变量名的构成原则是标识符,前面必须有 “*”, 表示该变量的类型是指针型变量。 (2)在一个定义语句中,可以同时定义普通变量、数组、 指针变量。 (3)类型说明符说明的数据类型不是指针变量中存放的 数据的数据类型,而是它将要指向的变量或数组的数据 类型。因此,一个指针变量只能用来指向同种数据类型 的其他变量或数组,不能时而指向一个浮点型变量,时 而指向一个整型变量。
说明:
(3)如果已执行了语句p=&a; ,则: &*p:先进行*p的运算,即是变量a,再执行&运算, 即变量a的地址。因此&*p与&a相同。 *&a:先进行&a的运算,即得a的地址,再执行*运 算, 即&a所指向的变量,即变量a。 因此*&a与a相同。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

9.4 按值调用与按地址调用
【例9.4】演示按值调用
return仅限于 从函数返回一个值
2017/9/7
24/46
例9.6:编写函数实现两数的互换
程序 1 Trace the execution
程序 2
int main() 主调函数 { int a, b; a = 5; b = 9; Swap(a, b); 实 参 printf("a=%d,b=%d",a,b); return 0; }
void Swap(int x,int y) { int temp; temp = x; x = y; y = temp; }
2017/9/7
被调 函数
形 参
结果有何不同?
主调函数
例9.6:编写函数实现两数的互换
被调函数
int main() { int a, b; a = 5; b = 9; Swap(a, b); printf("a=%d,b=%d",a,b); return 0; }
【例9.2】使用指针变量在屏幕上显示变量的地址值
Pointers have names, types and values
2017/9/7
15/46
9.2指针变量的定义和初始化
指针变量指向的数据类型称为基类型 【例 9.2】使用指针变量在屏幕上显示变量的地址值
指针变量只能指向同一基类型的变量
2017/9/7
2017/9/7
30/46
9.5用指针变量作函数参数的程序实例

【例9.7】计算并输出最高分及相应学生的学号
2017/9/7
31/46
9.5用指针变量作函数参数的程序实例

【例9.7】计算并输出最高分及相应学生的学号
真正的原因:普通变量作函数参数按值调用 不能在被调函数中改变相应的实参值
2017/9/7
void Swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp;
}
指针pTemp被赋了值 但交换的是地址值 不是指针指向单元的内容
2017/9/7 29/46
9.5用指针变量作函数参数的程序实例

【例9.7】计算并输出最高分及相应学生的学号
void Swap(int *x, int *y) { int temp; temp = *x; *x = *y; *y = temp;
}
指针pTemp未初始化 指针pTemp指向哪里未知 对未知单元写操作是危险的
2017/9/7
永远要清楚: 每个指针指向了哪里 指针指向的内容是什么
28/46
void Swap(int *x, int *y) { int *pTemp; pTemp = x; x = y; y = pTemp; }
2017/9/7
&a 0x0037b000 0x0037b001 0x0037b002 0x0037b003
某存储区域
8/46
9.1变量的内存地址
间接寻址:通过存放变量地址的变量去访问变量 如何读写内存中的数据?
int a=0; 0 a 0 0 0 Contents Contents Contents Contents Contents Contents 0x0037b000
5/46
变量的地址
&a 0x0037b000 0x0037b001 0x0037b002 0x0037b003
Address Operator
2017/9/7
某存储区域
9.1变量的内存地址
只要指明要访问的变量的内存单元地址 就可以立即访问到变量所在的存储单元
如何读写内存中的数据?
int a=0; 0 a 0
void Swap(int x, int y) { int temp; temp = x; x = y; y = temp; }
temp
5 x 9 5 y 9 5
形 参
实 参
a 5
b 9
2017/9/7
a
b
x
y x 和 y是内部变量 26/46
单向值传递
主调函数
例9.6:编写函数实现两数的互换
被调函数
2017/9/7
某存储区域
4/46
9.1变量的内存地址
内存中的每个字节都有唯一的编号(地址) 地址是一个十六进制无符号整数 其字长一般与主机相同 地址按字节编号,按类型分配空间 int a=0; 0 a 0 0 0 Contents Contents Contents Contents Contents Contents Contents
int main() { int a, b; a = 5; b = 9; Swap(a, b); printf("a=%d,b=%d",a,b); return 0; } void Swap(int x,int y) { int temp; temp = x; x = y; y = temp; }
2017/9/7
32/46
9.5用指针变量作函数参数的程序实例

【例9.7】计算并输出最高分及相应学生的学号
2017/9/7
33/46
9.5用指针变量作函数参数的程序实例

【例9.7】计算并输出最高分及相应学生的学号
2017/9/7
34/46
9.6函数指针及其应用

函数指针(Function Pointers)就是指向函数的指针(Pointer to a Function)
【例9.1】使用取地址运算符&取出变量的地址, 然后将其显示在屏幕上。
表示输出变量a的地址值?
2017/9/7
7/46
9.1变量的内存地址
直接寻址:按变量地址存取变量值
如何读写内存中的数据?
int a=0; 0 a 0
0 0 Contents Contents Contents Contents Contents scanf("%d", &a); Contents Contents
【例9.2】使用指针变量在屏幕上显示变量的地址值 指针变量使用之前必须初始化 Never use uninitialized pointers
2017/9/7
13/46
9.2指针变量的定义和初始化
【例9.2】使用指针变量在屏幕上显示变量的地址值
2017/9/7
14/46
9.2指针变量的定义和初始化
pa
0 9
*pa
a
引用指针所指向的变量的值 称为指针的解引用(Pointer Dereference)
2017/9/7
19/46
9.4 按值调用与按地址调用

普通变量作函数参数——按值调用(Call by Value) – Can not modify the argument 形参(Parameter)← 实参变量(Variable) 指针作函数参数——按地址调用(Call by Reference )
16/46
9.2指针变量的定义和初始化
【例9.2】使用指针变量在屏幕上显示变量的地址值
不能写成:int *pa, pb;
2017/9/7
17/46
9.3 间接寻址运算符
【例9.3】使用指针变量,通过间接寻址输出变量的值 &a
pa
0
*pa
a
2017/9/7
18/46
9.3 间接寻址运算符
【例9.3】使用指针变量,通过间接寻址输出变量的值 &a
int main() { int a, b; a = 5; b = 9; Swap( &a, &b ); printf("a=%d,b=%d",a,b); return 0; }
void Swap(int *x,int *y) { int temp; temp = *x; *x = *y; *y = temp; } 25/46
35/46
–忘掉了后一个(),写成

–定义时后一个括号内的参数类型与指向的函数参数类型不匹配
2017/9/7
9.6函数指针及其应用
9/46
&a 0x0037b000 0x0037b001 0x0037b002 0x0037b003
2017/9/7
某存储区域

int i; scanf("%d", i); /* 这样会如何?*/ char c; scanf("%d", &c); /* 这样呢?*/
i的值被当做地址。如i==100, 则输入的整数就会从地址100开 始写入内存
程序 2:指针变量作函数参数
int main() 指针为函数 { int a, b; 提供修改变 a = 5; 量值的手段 b = 9; Swap( &a, &b ); printf("a=%d,b=%d",a,b); return 0; } void Swap(int *x,int *y) { int temp; temp = *x; *x = *y; *y = temp; } 3/46
指向函数的指针变量存储的是函数在内存中的入口地址 编译器将不带()的函数名解释为该函数的入口地址 数据类型 (* 指针名)();

例如:int (*p)();

常见错误: –忘记了前一个(),写成

int *p(); /*声明一个函数名为p、返回值是整型指针的函数*/ int (*p); /*定义了一个整型指针*/
第9章 指针
哈尔滨工业大学 计算机科学与技术学院 苏小红
相关文档
最新文档