内容正文:
8.5节:指针作为函数参数
编程语言基础——C语言
同步精品课堂
高教版(第5版)
掌握国家标准《机械制图》中有关图幅、比例、字体图线等基本规定。
教学目标
一
03
学会使用字符数组名和字符指针变量作为函数参数实现字符串复制的不同方式
能够区分指针参数传递与普通变量参数传递的本质区别
04
掌握数组名作为函数参数对数组元素进行逆序操作的实现方法
02
理解指针变量作为函数参数时实现数据交换的原理
01
教学重难点
二
03
区分字符指针不同形式作为函数参数的使用场景
正确运用指针参数进行函数调用和内存操作
04
理解数组名作为函数参数时对数组元素操作的原理
02
掌握指针变量作为函数参数实现两数交换的地址传递机制
01
导入新课
三
指针"快递员"的三种送货方式
指针参数的三种魔法
交换两数:两个数字需要真正交换位置
倒序数组:多个数据需要批量处理
复制字符串:大量字符需要高效传递
问题:"如果用普通快递员,这些任务能完成吗?"
新知讲授
四
函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中。
接下来我们将通过多个程序示例,让同学们深入了解“指针变量”作为函数参数时的执行过程。
概述
新知讲授
四
知识点1:指针变量作为函数参数
例题8-13:从键盘上输入2个整数,并将它们交换后输出。
main( )
{ void swap( int *q1, int *q2 );
int a, b, *p1, *p2;
printf("输入2个整数:
");
scanf ("%d %d", &a, &b );
p1 = &a; /* ① */
p2 = &b; /* ② */
swap ( p1, p2 ); /* ③ */
printf("
交换后的2个整数:
");
printf("%d %d
", a , b ); /* ⑦ */
}
a b
p1 → 3 p2 → 7
*p1 *p2
执行①、②后,指针p1和p2的指向
a b
q1 → p1 → 3 q2 → p2 → 7
*p1,*q1 *p2,*q2
执行③后,指针p1、p2、q1、q2的指向
新知讲授
四
知识点1:指针变量作为函数参数
例题8-13:从键盘上输入2个整数,并将它们交换后输出。
#include <stdio.h>
void swap( int *q1, int *q2 )
{ int temp;
temp = *q1; /* ④ */
*q1 = *q2 ; /* ⑤ */
*q2 = temp; /* ⑥ */
}
temp a b
3 p1,q1 → 7 p2,q2 → 3
temp=*q1 *p1,*q1 *p2,*q2
执行④⑤⑥后
新知讲授
四
知识点1:指针变量作为函数参数
例题8-13:从键盘上输入2个整数,并将它们交换后输出。(简化版)
#include <stdio.h>
void swap( int *q1, int *q2 )
{ int temp; //temp为中间变量
temp = *q1; //将q1地址中的值取出并赋给temp
*q1 = *q2 ; //将q2地址中的值取出并替换q1指向的内存空间中的值
*q2 = temp; //将temp中的值取出并替换q2指向的内存空间的值
}
main( )
{ int a, b;
printf("输入2个整数:
");
scanf ("%d %d", &a, &b );
swap(&a,&b); //实参为变量a和变量b的地址
printf("
交换后的2个整数:
");
printf("%d %d
", a , b ); }
想通过函数调用得到n个要改变的值,可以用n个指针变量作实际参数,将这n个变量的地址传递给所调用函数的形参,然后通过形参指针变量间接访问的方式改变n个变量的值。
新知讲授
四
知识点1:指针变量作为函数参数
例题:对输入的两个整数按大小顺序输出(本例交换a和b的值,而p1和p2的值不变)
#include <stdio.h>
main()
{ void swap(int *p1,int *p2); //对swap函数的声明
int a,b;
int *pointer_1,*pointer_2;
//定义两个int *型的指针变量
printf("please enter a and b:");
scanf("%d,%d",&a,&b);//输入两个整数
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a<b)
swap(pointer_1,pointer_2); //如果a<b,调用swap函数
printf("max=%d,min=%d
",a,b); //输出结果
}
pointer_1 a
&a → 5
pointer_2 b
&b → 9
新知讲授
四
知识点1:指针变量作为函数参数
例题:对输入的两个整数按大小顺序输出(本例交换a和b的值,而p1和p2的值不变)
#include <stdio.h>
main()
{ ……
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a<b) //如果a<b,调用swap函数
swap(pointer_1,pointer_2);
…… }
void swap(int *p1,int *p2) //定义swap函数
{ int temp;
//使*p1和*p2互换
temp=*p1;
*p1=*p2;
*p2=temp; }
p1
&a a
pointer_1 5
&a
p2
&b b
pointer_2 9
&b
p1
&a a
pointer_1 9
&a
p2
&b b
pointer_2 5
&b
pointer_1 a
&a → 9
pointer_2 b
&b → 5
新知讲授
四
知识点1:指针变量作为函数参数
例题:对输入的两个整数按大小顺序输出(本例交换a和b的值,而p1和p2的值不变)
#include <stdio.h>
main()
{ void swap(int *p1,int *p2); //对swap函数的声明
int a,b;
int *pointer_1,*pointer_2;
//定义两个int *型的指针变量
printf("please enter a and b:");
scanf("%d,%d",&a,&b); //输入两个整数
pointer_1=&a; //使pointer_1指向a
pointer_2=&b; //使pointer_2指向b
if(a<b)
swap(pointer_1,pointer_2); //如果a<b,调用swap函数
printf("max=%d,min=%d
",a,b); //输出结果
}
//定义swap函数
void swap(int *p1,int *p2)
{ int temp;
//使*p1和*p2互换
temp=*p1;
*p1=*p2;
*p2=temp; }
新知讲授
四
知识点1:指针变量作为函数参数
例题:对输入的两个整数按大小顺序输出(本例交换a和b的值,而p1和p2的值不变)
void swap(int *p1,int *p2)
{ int temp;
temp=*p1;
*p1=*p2;
*p2=temp; }
void swap(int x,int y)
{ int temp;
temp=x;
x=y;
y=temp; }
void swap(int *p1,int *p2)
{ int *temp;
*temp=*p1;
*p1=*p2;
*p2=*temp; }
*p1就是a,是整型变量。而*temp是指针变量temp所指向的变量。但由于未给temp赋值,因此temp中并无确定的值,所以temp所指向的单元也是不可预见的
a b
5 9
↓ ↓
5 9
x y
a b
5 9
9 5
x y
未实现程序要求
新知讲授
四
知识点1:指针变量作为函数参数
例题:对输入的两个整数按大小顺序输出(本例交换a和b的值,而p1和p2的值不变)
void swap(int *p1,int *p2) //形参是指针变量
{ int *p;
p=p1; //下面3行交换p1和p2的指向
p1=p2;
p2=p;
}
pointer_1 a
&a → 5
pointer_2 b
&b → 9
p1 a
&a → 5
p2 b
&b → 9
p1 a
&b 5
p2 b
&a 9
pointer_1 a
&a → 5
pointer_2 b
&b → 9
不能企图通过改变指针形参的值而使指针实参的值改变
新知讲授
四
知识点2:使用数组名作为函数参数
例题:将数组a中n个整数按相反顺序存放。
#include <stdio.h>
void inv(int *x,int n)
{ int *p,temp,*i,*j,m=(n-1)/2;
i=x;
j=x+n-1;
p=x+m;
for(;i<=p;i++,j--)
{ temp=*i;
*i=*j;
*j=temp;} //*i与*j交换
}
main()
{ int i,a[10]={3,7,9,11,0,6,7,5,4,2};
printf("The original array:
");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("
");
inv(a,10);
printf("The array has been inverted:
");
for(i=0;i<10;i++)
printf("%d ",a[i]);
printf("
");
}
新知讲授
四
知识点2:使用数组名作为函数参数
例题:将数组a中n个整数按相反顺序存放。
#include <stdio.h>
void inv(int *x,int n) //形参x是指针变量
{ int *p,temp,*i,*j,m=(n-1)/2;
i=x; j=x+n-1; p=x+m;
for(;i<=p;i++,j--)
{temp=*i; *i=*j; *j=temp;}//*i与*j交换
}
main()
{int i,a[10]={3,7,9,11,0,6,7,5,4,2};
……
inv(a,10);
…… }
3 7 9 11 0 6 7 5 4 2
↑ ↑ ↑
i m j
2 4 5 7 6 0 11 9 7 3
i, x a数组
3 a[0]
7 a[1]
9 a[2]
p=x+m 11 a[3]
0 a[4]
6 a[5]
7 a[6]
5 a[7]
j 4 a[8]
2 a[9]
新知讲授
四
知识点2:使用数组名作为函数参数
小结
如果有一个实参数组,要想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下4种情况。
① 形参和实参都用数组名
② 实参用数组名,形参用指针变量。
③ 实参形参都用指针变量。
④ 实参为指针变量,形参为数组名。
①
int main()
{ int a[10];
f(a,10);
}
int f(int x[], int n)
{
}
②
int main()
{ int a[10];
f(a,10);
}
int f(int *x, int n)
{
}
③
int main()
{ int a[10];*p=a;
f(p,10);
}
int f(int *x, int n)
{
}
④
int main()
{ int a[10];*p=a;
f(p,10);
}
int f(int x[], int n)
{
}
新知讲授
四
知识点3:字符指针作为函数参数
例题:用函数调用实现字符串的复制。①用字符数组名作为函数参数
#include <stdio.h>
main()
{ void copy_string(char from[], char to[]);
char a[]="I am a teacher.";
char b[]="You are a student.";
printf("string a=%s
string b=%s
",a,b);
printf("copy string a to string b:
");
copy_string(a,b); //用字符数组名作为函数实参
printf("
string a=%s
string b=%s
",a,b); }
void copy_string(char from[], char to[]) //形参为字符数组
{ int i=0;
while(from[i]!='\0')
{ to[i]=from[i]; i++;}
to[i]='\0'; }
新知讲授
四
知识点3:字符指针作为函数参数
例题:用函数调用实现字符串的复制。②用字符型指针变量作实参
#include <stdio.h>
main()
{ void copy_string(char from[], char to[]); //函数声明
char a[]="I am a teacher."; //定义字符数组a并初始化
char b[]="You are a student."; //定义字符数组b并初始化
char *from=a,*to=b; //from指向a数组首元素,to指向b数组首元素
printf("string a=%s
string b=%s
",a,b);
printf("copy string a to string b:
");
copy_string(from,to); //实参为字符指针变量
printf("
string a=%s
string b=%s
",a,b); }
void copy_string(char from[], char to[]) //形参为字符数组
{ int i=0;
while(from[i]!='\0')
{ to[i]=from[i]; i++;} to[i]='\0'; }
新知讲授
四
知识点3:字符指针作为函数参数
例题:用函数调用实现字符串的复制。③用字符指针变量作形参和实参
#include <stdio.h>
main()
{ void copy_string(char *from, char *to);
char *a="I am a teacher."; //a是char*型指针变量
char b[]="You are a student."; //b是字符数组
char *p=b; //使指针变量p指向b数组首元素
printf("string a=%s
string b=%s
",a,b); //输出a串和b串
printf("copy string a to string b:
");
copy_string(a,p); //调用copy_string函数,实参为指针变量
printf("
string a=%s
string b=%s
",a,b); } //输出改变后的a串和b串
void copy_string(char *from, char *to) //定义函数,形参为字符指针变量
{ for(;*from!='\0';from++,to++)
{ *to=*from; }
*to='\0'; }
师生互动
五
指针参数身份鉴定——你能识别它们吗?
// 代码1
void swap(int *x, int *y) {
int temp = *x;
*x = *y;
*y = temp;
} // 代码2
void reverse(int a[], int n) {
int i, j, temp;
for(i=0,j=n-1; i<j; i++,j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
} // 代码3
void str_copy(char *dest, const char *src)
{
while(*dest++ = *src++);
}
基础任务:
快速判断每个函数使用的是哪种指针参数
说明该参数类型的典型应用场景 进阶任务:
为每个函数写出正确的调用代码
解释为什么不能用普通变量代替指针参数
尝试修改代码实现不同功能(如字符串连接)
随堂练习
六
1.下列关于指针作为函数参数的描述中,错误的是( )
A. 指针作为函数参数可以实现"传址调用"
B. 指针作为函数参数可以改变主调函数中指针变量的值
C. 指针作为函数参数可以改变主调函数中指针变量所指向的内容
D. 指针作为函数参数传递的是地址值
答案:B
解析:指针作为函数参数传递的是地址值,在函数内部可以修改指针所指向的内容,但不能修改主调函数中指针变量本身的值(即不能改变指针变量的指向)。
随堂练习
六
2.以下函数的功能是交换两个整型变量的值,正确的调用方式是( )
void swap(int *p, int *q) {
int temp = *p;
*p = *q;
*q = temp;
}
A. swap(a, b);
B. swap(&a, &b);
C. swap(*a, *b);
D. swap(int a, int b);
答案:B
解析:swap函数需要两个指针参数,因此调用时需要传递变量的地址。
随堂练习
六
3.以下程序的输出结果是( )
#include <stdio.h>
void fun(int *x) {
*x = 5;
}
main() {
int a = 10;
fun(&a);
printf("%d", a);
}
答案:5
解析:通过指针参数修改了main函数中变量a的值。
随堂练习
六
4.以下关于数组名作为函数参数的描述中,正确的是( )
A. 数组名作为参数传递的是整个数组的副本
B. 数组名作为参数传递的是数组的首地址
C. 数组名作为参数传递的是数组的长度
D. 数组名不能作为函数参数
答案:B
解析:数组名作为函数参数时传递的是数组的首地址,因此函数内部可以修改数组元素的值。
随堂练习
六
5.以下程序的输出结果是( )
#include <stdio.h>
void change(char *s) {
s[0] = 'H';
}
main() {
char str[] = "hello";
change(str);
printf("%s", str);
}
答案:Hello
解析:通过字符指针参数修改了字符串的第一个字符。
随堂练习
六
6.以下程序的输出结果是( )
#include <stdio.h>
void fun(int *p, int n) {
int i;
for(i = 0; i < n; i++) {
*(p + i) += 2;
}
}
main() {
int a[3] = {1, 2, 3};
fun(a, 3);
printf("%d,%d,%d", a[0], a[1], a[2]);
}
答案:3,4,5
解析:通过指针参数修改了数组的所有元素,每个元素加2。
随堂练习
六
7.以下程序的输出结果是( )
#include <stdio.h>
void f(char *p) {
p = "world";
}
main() {
char *s = "hello";
f(s);
printf("%s", s);
}
答案:hello
解析:函数f中修改的是形参指针p的指向,不会影响实参s的指向。
随堂练习
六
8.以下程序的输出结果是( )
#include <stdio.h>
void swap(int *x, int *y) {
int *t = x;
x = y;
y = t;
}
main() {
int a = 5, b = 10;
swap(&a, &b);
printf("%d,%d", a, b);
}
答案:5,10
解析:swap函数交换的是形参指针x和y的值,不影响实参a和b的值。
课堂小结
七
谢谢
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
EV录屏5.4.2软件录制
Lavf58.33.100
本视频由湖南一唯信息科技开发的EV录屏软件录制, www.ieway.cn
$