本次课的内容是,
1、预处理命令
2、指针和指针变量的概念
3、指针变量的使用
1) 宏定义
2)文件包含
3)条件编译
第 9章 预处理命令
?作用,对源程序编译之前做一些处理,生成扩展名
为的 C源程序
?种类
?宏定义 #define
?文件包含 #include
?条件编译 #if--#else--#endif 等
?格式,
?,#”开头
?占单独书写行
?语句尾不加分号
§ 9.1 宏定义
?不带参数宏定义
?一般形式,#define 宏名 字符串
?功能,用指定标识符 (宏名 )代替字符串
如 #define YES 1
#define NO 0
#define PI 3.1415926
#define OUT printf(“Hello,World”);
?定义位置,任意 (一般在函数外面 )
?作用域,从定义命令到文件结束
?#undef可 终止宏名作用域
格式,#undef 宏名
例 #define YES 1
main()
{ …….,
}
#undef YES
#define YES 0
max()
{…….,
}
YES原作用域
YES新作用域
?宏展开:预编译时,用字符串替换宏名 --
-不作语法检查
?引号中的内容与宏名相同也不置换
例 #define PI 3.14159
printf(“2*PI=%f\n”,PI*2);
宏展开,printf(“2*PI=%f\n”,3.14159*2);
如 if(x==YES) printf(“correct!\n”);
else if (x==NO) printf(“error!\n”);
展开后,if(x==1) printf(“correct!\n”);
else if (x==0) printf(“error!\n”);
例 #define MAX MAX+10 (?)
?宏定义可嵌套,不能递归
?宏定义中使用必要的括号 ()
例 #define WIDTH 80
#define LENGTH WIDTH+40
var=LENGTH*2;
宏展开,var= 80+40 *2;
( )
( )
例 #define WIDTH 80
#define LENGTH WIDTH+40
var=LENGTH*2;
宏展开,var= 80+40 *2;
?带参数宏定义
?一般形式,#define 宏名 (参数表 ) 字符串
例 #define S (r) PI*r*r
相当于定义了不带参宏 S,代表字符串,(r) PI*r*r”
?宏展开,形参用实参换,其它字符保留
?宏体及各形参外一般应加括号 ()
例 #define S(a,b) a*b
……….,
area=S(3,2);
宏展开, area=3*2;
不能加空格
例 #define POWER(x) x*x
a=4; b=6;
z=POWER(a+b);
宏展开,z=a+b*a+b;
一般写成,#define POWER(x) ((x)*(x))
宏展开,z=((a+b)*(a+b));
§ 9.2 文件包含
?功能:一个源文件可将另一个源文件的内容全部
包含进来
?一般形式,#include,文件名,
或 #include <文件名 >
#include,file2.c”
file1.c
file2.c
file1.c
B
A
B
A
?处理过程:预编译时,用被包含文件的内容取代
该预处理命令,再对“包含”后的文件作一个源
文件编译
<> 直接按标准目录搜索
“” 先在 当前目录 搜索,再搜索标准目录
可指定路径
例如,
/* file1.c */ /* file2.c */
#include,file2.c” max(int x,int y)
main() {int z;
{int a,b,c; z=x>y?x:y;
scanf(“%d,%d”,&a,&b); return(z);
c=max(a,b); }
printf(“Max is,%d”,c);
}
运行程序时,在编译前执行预处理命令,
结果为,
max(int x,int y)
{int z;
z=x>y?x:y;
return(z);
}
main()
{int a,b,c; scanf(“%d,%d”,&a,&b);
c=max(a,b);
printf(“Max is,%d”,c);
}
?被包含文件内容
?源文件 (*.c)
?头文件 (*.h) 宏定义 数据结构定义
函数说明等 ?文件包含可嵌套
#include,file2.c”
file1.c
A
file3.c
C
#include,file3.c”
file2.c
B
file1.c
A
file3.c
file2.c
也可以在 file1中用两个 include命令分别包含 file2和 file3,
#include "file3.h"
#include "file2.h"
file3应出现在
file2之前
§ 9.2 条件编译
?功能:源文件中的一部分内 容 只在满足一定
条件下才进行编译。
?三种形式,
1,#ifdef 标识符
程序段 1
[ #else
程序段 2 ]
#endif
当所指定的标识符已经被 #define命令定义过时,
则在程序编译阶段只编译程序段 1,否则编译
程序段 2。 #else可以没有。
2,#ifndef 标识符
程序段 1
#else
程序段 2
#endif
当所指定的标识符未被 #define命令定义过时,
则在程序编译阶段只编译程序段 1,否则编译
程序段 2。 #else可以没有。
3,#if 表达式
程序段 1
[ #else
程序段 2 ]
#endif
当所指定的表达式值为真 (非零 )时,则在程序编
译阶段只编译程序段 1,否则编译程序段 2。
#else可以没有。
例 输入一行字
母字符,根据需
要设置条件编译,
使之能将字母全改
写为大写输出,
或小写字母输出。
#define LETTER 1
main()
{char srt[20]="CLanguage",c;
int i;
i=0;
while((c=str[i]) !='\0')
{i++;
#if LETTER
if(c>='a' && c<='z')
c=c-32;
#else
if(c>='A' && c<='Z')
c=c+32;
#endif
printf("%c",c);
}
}
运行结果,
CLANGUAGE
第十章 指针
指针是 C语言中一个非常重要的概念,也是一个
使用灵活、用途广泛、初学者难以把握的一个
概念。指针的重要性可以说,学习 C语言如果不
掌握指针的基本使用就没有真正掌握 C语言的精
华。
C程序设计中使用指针可以,
?使程序简洁、紧凑、高效
?有效地表示复杂的数据结构
?动态分配内存
?得到多于一个的函数返回值
§ 10.1 指针的概念
?变量与地址
程序中, int i;
float k;
内存中每个字节有一个编号 -----地址
…...
…...
2000
2001
2002
2005
内存
0
2003
i
k
编译或函数调用时为其分配内存单元
XXX
XXX i
k
2000
2002
…...
…...
2000
2004
2006
2005
整型变量 i
10
变量 i_pointer
2001
2002
2003
?指针与指针变量
?指针:一个变量的地址
?指针变量:专门存放变量地址的变量叫 ~
2000
指针
指针变量
变量 i的 内容 变量的 地址
int i=10;
2000
25
2000
i i_pointer
指针变量与它所指变量之间的示意图
i_pointer是指针变
量其值是地址。
i是基本整型变量
其值存在地址为
2000的存储单元
内。
§ 10.2 指针变量
一,指针变量的定义方法
指针变量的定义格式,
基类型 *指针变量名;
含义:定义一个指向基类型的指针变量。
注意,
1,若有 int *p1,*p2;
则 指针变量名是 p1,p2,不是 *p1,*p2
2,指针变量只能指向定义时所规定类型的变量
3、指针变量定义后,变量值不确定,应用前必须先赋值
例如,int *pointer_1;
float *pointer_2;
则指针变量 pointer_1和 pointer_2 可以分别指向
基本整型变量和单精度实型变量。
二、如何让 指针变量 指向一个 变量?
例如:有以下定义
int i ; float a;
int *pointer_1; float *pointer_2;
要想让指针变量 pointer_1指向整型变量 i,指针
变量 pointer_2指向实型变量 a,可以用下面赋
值语句,
pointer_1=&i;
pointer_2=&a;
&i
&a
pointer_1
pointer_2
i 2000
a 3000
三, 如何用指针变量表示它所指向的变量?
例如,
2000
pointer_1 j
2000
则如何用 pointer_1指针变量来表示变量 j?
C语言提供一种新的运算,运算符为, *,,
称为指针运算符(也称, 间接访问, 运算符)。
指针变量经过, *” 运算后,就成为他所指
向的变量,既 *pointer_1就表示变量 j 。
2000 10
j_pointer *j_pointer j
2000
即:若
int j=10;
int *j_pointer;
j_pointer=&j;
则有右边示意图
四、直接访问和间接访问
直接访问:按变量地址存取变量值
间接访问:通过指针变量去存储变量值
由上面的运算可以得到给变量 j 赋值的两种方法,
即 ① j=30; ② *j_pointer=30
第一种方法是直接由变量 j的地址存取值,第二种方法是通过指针
变量取到 j的地址,然后通过该地址操作存储单元。见下面示意图
直接访问与间接访问的示意图
例 j=3; -----直接访问
指针变量
…...
…...
2000
2004
2006
2005
整型变量 j
10
变量 j_pointer
2001
2002
2003
2000
3
例 *j_pointer=30; -----间接访问
30
五、指针变量的初始化
一般形式,数据类型 *指针名 =初始地址值 ;
赋给指针变量,
不是赋给目标变量
例 int i;
int *p=&i; 变量必须 已说明过
类型 应一致
例 int *p=&i;
int i;
例 int i;
int *p=&i;
int *q=p; 用已初始化指针变量作初值
六、两种运算 &与 * 的比较
&,是求地址运算符 *:指针运算符
这两种运算均为一元运算、优先级相同、均为右结合。
两者的关系:互为逆运算。
例如,int k;
int *p=&k;
则有:运算式 &*p 相当于 &(*p)结果是 &k 即 k的地
址 。
运算式 *&k 相当于 *(&k)结果就是变量 k,
&k
(3000)
k p
3000
*p
七、指针变量的使用
例 1:通过指针变量访问整型变量。 程序如下,
main()
{int a,b;
int *pointer_1;
int *pointer_2;
a=100;b=200;
pointer_1=&a;
pointer_2=&b;
printf(“a=%d,b=%d”,a,b);
printf(“a=%d,b=%d”,*pointer_1,*pointer_2);
}
&a
200
pointer_1
*pointer_1
a
&a *pointer_2
100
pointer_1
运行结果,
a=100,b=200
a= 100,b=200
例 2:观察下面程序的输出结果。
main()
{int a=10,b=20;
int *p,*q;
p=&a; q=&b;
printf(“1) %o,%o\n”,&a,&b);
printf(“2) %o,%o\n”,p,q);
printf(“3) %d,%d\n”,a,b);
printf(“4) %d,%d\n”,*p,*q);
}
运行结果,
1) 177724, 177726
2) 177724, 177726
3) 10, 20
4) 10,20
10
20
a 或 *p
b 或 *q
&a=177724
&b=177726
177725
177727
&a
&b
10
20
p
q
a
b
例 3, 输入 a 和 b 两个数,并使其从大到小输出 a 和 b 。
main()
{int *p1,*p2,*p,a,b;
scanf("%d,%d",&a,&b);
p1=&a; p2=&b;
if(a<b)
{p=p1; p1=p2; p2=p;}
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);
}
运行结果,a=5,b=9
max=9,min=5
&a
&b
5
9
p1 a
p2 b
p *p1
*p2
&a
&b
&a
5
9
a
b
p1
p2
p *p2
*p1
八、指针变量作为函数参数 ——地址传递
特点,共享内存,“双向, 传递
swap(int x,int y)
{ int temp;
temp=x; x=y; y=temp;
}
main()
{ int a,b;
scanf("%d,%d",&a,&b);
if(a<b) swap(a,b);
printf("\n%d,%d\n",a,b);
}
例 4:不使用指针的情况,题目和例 3相同,即 输入 a和 b
两个数,按大小顺序输出。 将数从大到小输出。 (值传递 )
x y
5 9 形参
temp
5 9
a
实参
b
输出结果, 5,9
swap(int *r1,int *r2)
{int r;
r=*r1;*r1=*r2; *r2=r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
对上例 使用指针变量(地址传递)
p,q为实参
&b
q
9
b
*q
&a
p
5
a
*p r
r1,r2为形参
&a
r1
*r1
&b
r2
*r2
输出结果,9, 5
思考,第一种情况
swap(int *r1,int *r2)
{int *r;
*r=*r1;*r1=*r2; *r2=*r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
r
&b
&a
r1
r2 b
a
&a
&b
p
q
5
9
不对
swap(int *r1,int *r2)
{int *r;
r=r1; r1=r2; r2=r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
思考,第二种情况
&a
&b
r1
r2
5
9
a
b
r
&b
&a
p
q
5
9
a
b
不对
练习,1、有如下语句,
int a=10,b=20,*p1,*p2;
p1=&a; p2=&b;
如图 1所示,若要实现图 2所示的存储结构,可以选用的赋
值语句是?
10 20
p1 p2
a b
图 1 图 2
10 20
p1 p2
a b
A *p1=*p2; B p1=p2
C p1=*p2 ; D *p1=p2
练习,
2,写出下面程序的运行结果,
sub(int x,int y,int *z)
{*z=y-x; }
main()
{int a,b ;
sub(10,5,&a); /* 第一次调子函数 */
sub(7,a,&b); /*第二次调子函数 */
printf(“%d,%d”,a,b);
}
分析过程,
第一次调子函数
10 5
a b
2000 3000
实参
形参 10 5 2000
x y z
*z
第二次调子函数
7 -5
2000 3000
实参
形参 7 -5 3000
x y z -5 -12
3,main()
{int *p,*q,a,b;
p=&a;
printf(“input a:”);
scanf(“%d”,*p); /*此语句错在什么地方? */
}
作业,9.2 10.1
1、预处理命令
2、指针和指针变量的概念
3、指针变量的使用
1) 宏定义
2)文件包含
3)条件编译
第 9章 预处理命令
?作用,对源程序编译之前做一些处理,生成扩展名
为的 C源程序
?种类
?宏定义 #define
?文件包含 #include
?条件编译 #if--#else--#endif 等
?格式,
?,#”开头
?占单独书写行
?语句尾不加分号
§ 9.1 宏定义
?不带参数宏定义
?一般形式,#define 宏名 字符串
?功能,用指定标识符 (宏名 )代替字符串
如 #define YES 1
#define NO 0
#define PI 3.1415926
#define OUT printf(“Hello,World”);
?定义位置,任意 (一般在函数外面 )
?作用域,从定义命令到文件结束
?#undef可 终止宏名作用域
格式,#undef 宏名
例 #define YES 1
main()
{ …….,
}
#undef YES
#define YES 0
max()
{…….,
}
YES原作用域
YES新作用域
?宏展开:预编译时,用字符串替换宏名 --
-不作语法检查
?引号中的内容与宏名相同也不置换
例 #define PI 3.14159
printf(“2*PI=%f\n”,PI*2);
宏展开,printf(“2*PI=%f\n”,3.14159*2);
如 if(x==YES) printf(“correct!\n”);
else if (x==NO) printf(“error!\n”);
展开后,if(x==1) printf(“correct!\n”);
else if (x==0) printf(“error!\n”);
例 #define MAX MAX+10 (?)
?宏定义可嵌套,不能递归
?宏定义中使用必要的括号 ()
例 #define WIDTH 80
#define LENGTH WIDTH+40
var=LENGTH*2;
宏展开,var= 80+40 *2;
( )
( )
例 #define WIDTH 80
#define LENGTH WIDTH+40
var=LENGTH*2;
宏展开,var= 80+40 *2;
?带参数宏定义
?一般形式,#define 宏名 (参数表 ) 字符串
例 #define S (r) PI*r*r
相当于定义了不带参宏 S,代表字符串,(r) PI*r*r”
?宏展开,形参用实参换,其它字符保留
?宏体及各形参外一般应加括号 ()
例 #define S(a,b) a*b
……….,
area=S(3,2);
宏展开, area=3*2;
不能加空格
例 #define POWER(x) x*x
a=4; b=6;
z=POWER(a+b);
宏展开,z=a+b*a+b;
一般写成,#define POWER(x) ((x)*(x))
宏展开,z=((a+b)*(a+b));
§ 9.2 文件包含
?功能:一个源文件可将另一个源文件的内容全部
包含进来
?一般形式,#include,文件名,
或 #include <文件名 >
#include,file2.c”
file1.c
file2.c
file1.c
B
A
B
A
?处理过程:预编译时,用被包含文件的内容取代
该预处理命令,再对“包含”后的文件作一个源
文件编译
<> 直接按标准目录搜索
“” 先在 当前目录 搜索,再搜索标准目录
可指定路径
例如,
/* file1.c */ /* file2.c */
#include,file2.c” max(int x,int y)
main() {int z;
{int a,b,c; z=x>y?x:y;
scanf(“%d,%d”,&a,&b); return(z);
c=max(a,b); }
printf(“Max is,%d”,c);
}
运行程序时,在编译前执行预处理命令,
结果为,
max(int x,int y)
{int z;
z=x>y?x:y;
return(z);
}
main()
{int a,b,c; scanf(“%d,%d”,&a,&b);
c=max(a,b);
printf(“Max is,%d”,c);
}
?被包含文件内容
?源文件 (*.c)
?头文件 (*.h) 宏定义 数据结构定义
函数说明等 ?文件包含可嵌套
#include,file2.c”
file1.c
A
file3.c
C
#include,file3.c”
file2.c
B
file1.c
A
file3.c
file2.c
也可以在 file1中用两个 include命令分别包含 file2和 file3,
#include "file3.h"
#include "file2.h"
file3应出现在
file2之前
§ 9.2 条件编译
?功能:源文件中的一部分内 容 只在满足一定
条件下才进行编译。
?三种形式,
1,#ifdef 标识符
程序段 1
[ #else
程序段 2 ]
#endif
当所指定的标识符已经被 #define命令定义过时,
则在程序编译阶段只编译程序段 1,否则编译
程序段 2。 #else可以没有。
2,#ifndef 标识符
程序段 1
#else
程序段 2
#endif
当所指定的标识符未被 #define命令定义过时,
则在程序编译阶段只编译程序段 1,否则编译
程序段 2。 #else可以没有。
3,#if 表达式
程序段 1
[ #else
程序段 2 ]
#endif
当所指定的表达式值为真 (非零 )时,则在程序编
译阶段只编译程序段 1,否则编译程序段 2。
#else可以没有。
例 输入一行字
母字符,根据需
要设置条件编译,
使之能将字母全改
写为大写输出,
或小写字母输出。
#define LETTER 1
main()
{char srt[20]="CLanguage",c;
int i;
i=0;
while((c=str[i]) !='\0')
{i++;
#if LETTER
if(c>='a' && c<='z')
c=c-32;
#else
if(c>='A' && c<='Z')
c=c+32;
#endif
printf("%c",c);
}
}
运行结果,
CLANGUAGE
第十章 指针
指针是 C语言中一个非常重要的概念,也是一个
使用灵活、用途广泛、初学者难以把握的一个
概念。指针的重要性可以说,学习 C语言如果不
掌握指针的基本使用就没有真正掌握 C语言的精
华。
C程序设计中使用指针可以,
?使程序简洁、紧凑、高效
?有效地表示复杂的数据结构
?动态分配内存
?得到多于一个的函数返回值
§ 10.1 指针的概念
?变量与地址
程序中, int i;
float k;
内存中每个字节有一个编号 -----地址
…...
…...
2000
2001
2002
2005
内存
0
2003
i
k
编译或函数调用时为其分配内存单元
XXX
XXX i
k
2000
2002
…...
…...
2000
2004
2006
2005
整型变量 i
10
变量 i_pointer
2001
2002
2003
?指针与指针变量
?指针:一个变量的地址
?指针变量:专门存放变量地址的变量叫 ~
2000
指针
指针变量
变量 i的 内容 变量的 地址
int i=10;
2000
25
2000
i i_pointer
指针变量与它所指变量之间的示意图
i_pointer是指针变
量其值是地址。
i是基本整型变量
其值存在地址为
2000的存储单元
内。
§ 10.2 指针变量
一,指针变量的定义方法
指针变量的定义格式,
基类型 *指针变量名;
含义:定义一个指向基类型的指针变量。
注意,
1,若有 int *p1,*p2;
则 指针变量名是 p1,p2,不是 *p1,*p2
2,指针变量只能指向定义时所规定类型的变量
3、指针变量定义后,变量值不确定,应用前必须先赋值
例如,int *pointer_1;
float *pointer_2;
则指针变量 pointer_1和 pointer_2 可以分别指向
基本整型变量和单精度实型变量。
二、如何让 指针变量 指向一个 变量?
例如:有以下定义
int i ; float a;
int *pointer_1; float *pointer_2;
要想让指针变量 pointer_1指向整型变量 i,指针
变量 pointer_2指向实型变量 a,可以用下面赋
值语句,
pointer_1=&i;
pointer_2=&a;
&i
&a
pointer_1
pointer_2
i 2000
a 3000
三, 如何用指针变量表示它所指向的变量?
例如,
2000
pointer_1 j
2000
则如何用 pointer_1指针变量来表示变量 j?
C语言提供一种新的运算,运算符为, *,,
称为指针运算符(也称, 间接访问, 运算符)。
指针变量经过, *” 运算后,就成为他所指
向的变量,既 *pointer_1就表示变量 j 。
2000 10
j_pointer *j_pointer j
2000
即:若
int j=10;
int *j_pointer;
j_pointer=&j;
则有右边示意图
四、直接访问和间接访问
直接访问:按变量地址存取变量值
间接访问:通过指针变量去存储变量值
由上面的运算可以得到给变量 j 赋值的两种方法,
即 ① j=30; ② *j_pointer=30
第一种方法是直接由变量 j的地址存取值,第二种方法是通过指针
变量取到 j的地址,然后通过该地址操作存储单元。见下面示意图
直接访问与间接访问的示意图
例 j=3; -----直接访问
指针变量
…...
…...
2000
2004
2006
2005
整型变量 j
10
变量 j_pointer
2001
2002
2003
2000
3
例 *j_pointer=30; -----间接访问
30
五、指针变量的初始化
一般形式,数据类型 *指针名 =初始地址值 ;
赋给指针变量,
不是赋给目标变量
例 int i;
int *p=&i; 变量必须 已说明过
类型 应一致
例 int *p=&i;
int i;
例 int i;
int *p=&i;
int *q=p; 用已初始化指针变量作初值
六、两种运算 &与 * 的比较
&,是求地址运算符 *:指针运算符
这两种运算均为一元运算、优先级相同、均为右结合。
两者的关系:互为逆运算。
例如,int k;
int *p=&k;
则有:运算式 &*p 相当于 &(*p)结果是 &k 即 k的地
址 。
运算式 *&k 相当于 *(&k)结果就是变量 k,
&k
(3000)
k p
3000
*p
七、指针变量的使用
例 1:通过指针变量访问整型变量。 程序如下,
main()
{int a,b;
int *pointer_1;
int *pointer_2;
a=100;b=200;
pointer_1=&a;
pointer_2=&b;
printf(“a=%d,b=%d”,a,b);
printf(“a=%d,b=%d”,*pointer_1,*pointer_2);
}
&a
200
pointer_1
*pointer_1
a
&a *pointer_2
100
pointer_1
运行结果,
a=100,b=200
a= 100,b=200
例 2:观察下面程序的输出结果。
main()
{int a=10,b=20;
int *p,*q;
p=&a; q=&b;
printf(“1) %o,%o\n”,&a,&b);
printf(“2) %o,%o\n”,p,q);
printf(“3) %d,%d\n”,a,b);
printf(“4) %d,%d\n”,*p,*q);
}
运行结果,
1) 177724, 177726
2) 177724, 177726
3) 10, 20
4) 10,20
10
20
a 或 *p
b 或 *q
&a=177724
&b=177726
177725
177727
&a
&b
10
20
p
q
a
b
例 3, 输入 a 和 b 两个数,并使其从大到小输出 a 和 b 。
main()
{int *p1,*p2,*p,a,b;
scanf("%d,%d",&a,&b);
p1=&a; p2=&b;
if(a<b)
{p=p1; p1=p2; p2=p;}
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);
}
运行结果,a=5,b=9
max=9,min=5
&a
&b
5
9
p1 a
p2 b
p *p1
*p2
&a
&b
&a
5
9
a
b
p1
p2
p *p2
*p1
八、指针变量作为函数参数 ——地址传递
特点,共享内存,“双向, 传递
swap(int x,int y)
{ int temp;
temp=x; x=y; y=temp;
}
main()
{ int a,b;
scanf("%d,%d",&a,&b);
if(a<b) swap(a,b);
printf("\n%d,%d\n",a,b);
}
例 4:不使用指针的情况,题目和例 3相同,即 输入 a和 b
两个数,按大小顺序输出。 将数从大到小输出。 (值传递 )
x y
5 9 形参
temp
5 9
a
实参
b
输出结果, 5,9
swap(int *r1,int *r2)
{int r;
r=*r1;*r1=*r2; *r2=r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
对上例 使用指针变量(地址传递)
p,q为实参
&b
q
9
b
*q
&a
p
5
a
*p r
r1,r2为形参
&a
r1
*r1
&b
r2
*r2
输出结果,9, 5
思考,第一种情况
swap(int *r1,int *r2)
{int *r;
*r=*r1;*r1=*r2; *r2=*r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
r
&b
&a
r1
r2 b
a
&a
&b
p
q
5
9
不对
swap(int *r1,int *r2)
{int *r;
r=r1; r1=r2; r2=r;
}
main()
{int a,b;
int *p,*q;
scanf("%d,%d",&a,&b);
p=&a; q=&b;
if(a<b)swap(p,q);
printf("\n%d,%d\n",a,b);
}
思考,第二种情况
&a
&b
r1
r2
5
9
a
b
r
&b
&a
p
q
5
9
a
b
不对
练习,1、有如下语句,
int a=10,b=20,*p1,*p2;
p1=&a; p2=&b;
如图 1所示,若要实现图 2所示的存储结构,可以选用的赋
值语句是?
10 20
p1 p2
a b
图 1 图 2
10 20
p1 p2
a b
A *p1=*p2; B p1=p2
C p1=*p2 ; D *p1=p2
练习,
2,写出下面程序的运行结果,
sub(int x,int y,int *z)
{*z=y-x; }
main()
{int a,b ;
sub(10,5,&a); /* 第一次调子函数 */
sub(7,a,&b); /*第二次调子函数 */
printf(“%d,%d”,a,b);
}
分析过程,
第一次调子函数
10 5
a b
2000 3000
实参
形参 10 5 2000
x y z
*z
第二次调子函数
7 -5
2000 3000
实参
形参 7 -5 3000
x y z -5 -12
3,main()
{int *p,*q,a,b;
p=&a;
printf(“input a:”);
scanf(“%d”,*p); /*此语句错在什么地方? */
}
作业,9.2 10.1