靳润昭C语言教程讲义 2001年2月17日 ″*p2=*p1;"实际上就是”ji;",前者不仅速度慢而且目的不明。但由于指针是变量,我们可以 通过改变它们的指向,以间接访问不同的变量,这给程序员带来灵活性,也使程序代码编写得 更为简洁和有效 指针变量可出现在表达式中,设 int x, y, *px=&x: 指针变量px指向整数x,则*px可出现在x能出现的任何地方。例如: y=*px+5;/表示把x的内容加5并赋给y*/ ++*px;/*px的内容加上1之后赋给y,++*px相当于++(*px)*/ y=*px++;/*相当于y=*px;px++*/ 【例10.1】 main i int a, b: int *pointer l, *pointer 2 a=100;b=10; pointer l=&a pointer 2=&b printf(%d, %d\n", a, b) printf( %d, %d \n", *pointer 1, *pointer 2) 对程序的说明: 1)在开头处虽然定义了两个指针变量 pointer1和 pointer2,担它们并未指向任何一个 整型变量。只是提供两个指针变量,规定它们可以指向整型变量。程序第5、6行的作 用就是使 pointer1指向a, pointer2指向b。 nter 1 *pointer_ 1 pointer b *pointer 2 2)最后一行的* pointer1和* pointer2就是变量a和b。最后两个 printf函数作用是相 同的 3)程序中有两处出现* pointer1和* pointer2,请区分它们的不同含义 4)程序第5、6行的" pointer1a"和" pointer2=&b"不能写成“* pointer1=&a"和 pointer_2=&b"。 请对下面再的关于“&"和”*"的问题进行考虑: 1)如果已经执行了“ pointer1&a;"语句,则&* pointer1是什么含义? 第6页
靳润昭 C 语言教程讲义 2001 年 2 月 17 日 第6页 "*p2=*p1;"实际上就是"j=i;",前者不仅速度慢而且目的不明。但由于指针是变量,我们可以 通过改变它们的指向,以间接访问不同的变量,这给程序员带来灵活性,也使程序代码编写得 更为简洁和有效。 指针变量可出现在表达式中, 设 int x,y,*px=&x; 指针变量 px 指向整数 x,则*px 可出现在 x 能出现的任何地方。例如: y=*px+5; /*表示把 x 的内容加 5 并赋给 y*/ y=++*px; /*px 的内容加上 1 之后赋给 y,++*px 相当于++(*px)*/ y=*px++; /*相当于 y=*px; px++*/ 【例 10.1】 main() { int a,b; int *pointer_1, *pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1, *pointer_2); } 对程序的说明: 1) 在开头处虽然定义了两个指针变量 pointer_1 和 pointer_2,担它们并未指向任何一个 整型变量。只是提供两个指针变量,规定它们可以指向整型变量。程序第 5、6 行的作 用就是使 pointer_1 指向 a,pointer_2 指向 b。 2) 最后一行的*pointer_1 和*pointer_2 就是变量 a 和 b。最后两个 printf 函数作用是相 同的。 3) 程序中有两处出现*pointer_1 和*pointer_2,请区分它们的不同含义。 4) 程序第 5、6 行的“pointer_1=&a”和 “pointer_2=&b”不能写成“*pointer_1=&a”和 “*pointer_2=&b”。 请对下面再的关于“&”和“*”的问题进行考虑: 1) 如果已经执行了“pointer_1=&a;”语句,则&*pointer_1 是什么含义?
靳润昭C语言教程讲义 2001年2月17日 2)米&a含义是什么? 3)( pointer_1)++和 pointer1+的区别? 【例10.2】输入a和b两个整数,按先大后小的顺序输出a和b main I int * pl, *p 2, *p, a, b: scanf(%d, %d",&a, &b) pI=&a: p2=&b if(a<b) Ip=pl: p1=p2: p2=p printf("\na=%d, b=%d\n", a, b) printf("max=%d, min=%d\n"*p1, *p2) 1023指针变量作为函数参数 函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将 一个变量的地址传送到另一个函数中。 【例10.3】题目同例10.2,即输入的两个整数按大小顺序输出。今用函数处理,而且用指 针类型的数据作函数参数 swap (int *pl, int *p2) int te temp=*kpl kp2=temp main int a, b: int *pointer l, *pointer canf( %d, %d", &a, &b) pointer 1=&a; pointer 2=&b if(a<b) swap(pointer 1, pointer 2) printf("\n%d, %d\n", a, b) 对程序的说明: swap是用户定义的函数,它的作用是交换两个变量(a和b)的值。swap函数的形参 pl、p2是指针变量。程序运行时,先执行main函数,输入a和b的值。然后将a和b的地 址分别赋给指针变量 pointer_1和 pointer_2,使 pointer_1指向a, pointer2指向b 第7页
靳润昭 C 语言教程讲义 2001 年 2 月 17 日 第7页 2) *&a 含义是什么? 3) (pointer_1)++和 pointer_1++的区别? 【例 10.2】输入 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("\na=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1, *p2); } 10.2.3指针变量作为函数参数 函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将 一个变量的地址传送到另一个函数中。 【例 10.3】题目同例 10.2,即输入的两个整数按大小顺序输出。今用函数处理,而且用指 针类型的数据作函数参数。 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<b) swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); } 对程序的说明: swap 是用户定义的函数,它的作用是交换两个变量(a 和 b)的值。swap 函数的形参 p1、p2 是指针变量。程序运行时,先执行 main 函数,输入 a 和 b 的值。然后将 a 和 b 的地 址分别赋给指针变量 pointer_1 和 pointer_2,使 pointer_1 指向 a,pointer_2 指向 b
靳润昭C语言教程讲义 2001年2月17日 pointer 1 & ointer 2 b 9 接着执行ⅱf语句,由于a〈b,因此执行swap函数。注意实参 pointer1和 pointer2是 指针变量,在函数调用时,将实参变量的值传递给形参变量。采取的依然是"值传递〃方式 因此虚实结合后形参p1的值为&a,p2的值为&b。这时p1和 pointer1指向变量a,p2和 pointer2指向变量b ointer_1 x pointer 接着执行执行swap函数的函数体使*l和*p2的值互换,也就是使a和b的值互换。 a inter nter 2 &b 函数调用结束后,p1和p2不复存在(已释放)如图。 pointer pointer_2 b 最后在main函数中输出的a和b的值是己经过交换的值。 请注意交换*p1和*p2的值是如何实现的。请找出下列程序段的错误: swap(int *pl, int *p2) 冰te /*此语句有问题* 率pl=*p2 第8页
靳润昭 C 语言教程讲义 2001 年 2 月 17 日 第8页 接着执行 if 语句,由于 a〈b,因此执行 swap 函数。注意实参 pointer_1 和 pointer_2 是 指针变量,在函数调用时,将实参变量的值传递给形参变量。采取的依然是“值传递”方式。 因此虚实结合后形参 p1 的值为&a,p2 的值为&b。这时 p1 和 pointer_1 指向变量 a,p2 和 pointer_2 指向变量 b。 接着执行执行 swap 函数的函数体使*p1 和*p2 的值互换,也就是使 a 和 b 的值互换。 函数调用结束后,p1 和 p2 不复存在(已释放)如图。 最后在 main 函数中输出的 a 和 b 的值是已经过交换的值。 请注意交换*p1 和*p2 的值是如何实现的。请找出下列程序段的错误: swap(int *p1,int *p2) {int *temp; *temp=*p1; /*此语句有问题*/ *p1=*p2; *p2=temp;
靳润昭C语言教程讲义 2001年2月17日 请考虑下面的函数能否实现实现a和b互换 swap(int x, int y) 如果在main函数中用"swap(a,b);"调用swap函数,会有什么结果呢?请看下图所示。 b 【例10.4】请注意,不能企图通过改变指针形参的值而使指针实参的值改变。 swap (int *pl, int *p2) int水 maino int *pointer 1, *pointer 2 pointer l=&a; pointer 2=&b if(a<b) swap(pointer 1, pointer 2) printf( \n%d, %d\n", *pointer 1, *pointer 2) 其中的问题在于不能实现如图所示的第四步(d)。 pointer pointer 1 a pointer_2 b ointer 2 【例10.5】输入a、b、c3个整数,按大小顺序输出。 第9页
靳润昭 C 语言教程讲义 2001 年 2 月 17 日 第9页 } 请考虑下面的函数能否实现实现 a 和 b 互换。 swap(int x,int y) {int temp; temp=x; x=y; y=temp; } 如果在 main 函数中用“swap(a,b);”调用 swap 函数,会有什么结果呢?请看下图所示。 【例 10.4】请注意,不能企图通过改变指针形参的值而使指针实参的值改变。 swap(int *p1,int *p2) {int *p; p=p1; p1=p2; p2=p; } main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a;pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("\n%d,%d\n",*pointer_1,*pointer_2); } 其中的问题在于不能实现如图所示的第四步(d)。 【例 10.5】输入 a、b、c3 个整数,按大小顺序输出
靳润昭C语言教程讲义 2001年2月17日 swap (int *ptl, int *pt2) lint temp kptl=xpt exchange(int *ql, int *g2, int *q3) I if(*q1<*g2)swap(ql, g2) if(*q1<*g3)swap(ql, g3) if(=g2<*q3)swap(g2, g3) main int a, b, c, *pl, * kp2, *p3 scanf(%d, %d, %d", &a, &b, &c) pl=&a;p2=&b;p3=& exchange(p1, p2, p3) printf("\n%d, %d, %d \n,a, b, c) 10.24指针变量几个问题的进一步说明 指针变量可以进行某些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算 术运算及关系运算。 1.指针运算符 1)取地址运算符&:取地址运算符&是单目运算符,其结合性为自右至左,其功能是取变量 的地址。在 scanf函数及前面介绍指针变量赋值中,我们己经了解并使用了&运算符。 2)取内容运算符*:取内容运算符*是单目运算符,其结合性为自右至左,用来表示指针变 量所指的变量。在*运算符之后跟的变量必须是指针变量 需要注意的是指针运算符*和指针变量说明中的指针说明符*不是一回事。在指针变量说 明中,"*"是类型说明符,表示其后的变量是指针类型。而表达式中出现的*则是一个运 算符用以表示指针变量所指的变量 【例10.6】 t a=5, p printf ( %d",*p) 表示指针变量p取得了整型变量a的地址 printf("%d",*p)语句表示输出变量a的值 2.指针变量的运算 1)赋值运算:指针变量的赋值运算有以下几种形式。 第10页
靳润昭 C 语言教程讲义 2001 年 2 月 17 日 第10页 swap(int *pt1,int *pt2) {int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; } exchange(int *q1,int *q2,int *q3) { if(*q1<*q2)swap(q1,q2); if(*q1<*q3)swap(q1,q3); if(*q2<*q3)swap(q2,q3); } main() { int a,b,c,*p1,*p2,*p3; scanf("%d,%d,%d",&a,&b,&c); p1=&a;p2=&b; p3=&c; exchange(p1,p2,p3); printf("\n%d,%d,%d \n",a,b,c); } 10.2.4指针变量几个问题的进一步说明 指针变量可以进行某些运算,但其运算的种类是有限的。它只能进行赋值运算和部分算 术运算及关系运算。 1. 指针运算符 1) 取地址运算符&:取地址运算符&是单目运算符,其结合性为自右至左,其功能是取变量 的地址。在 scanf 函数及前面介绍指针变量赋值中,我们已经了解并使用了&运算符。 2) 取内容运算符*:取内容运算符*是单目运算符,其结合性为自右至左,用来表示指针变 量所指的变量。在*运算符之后跟的变量必须是指针变量。 需要注意的是指针运算符*和指针变量说明中的指针说明符*不是一回事。在指针变量说 明中,“*”是类型说明符,表示其后的变量是指针类型。而表达式中出现的“*”则是一个运 算符用以表示指针变量所指的变量。 【例 10.6】 main(){ int a=5,*p=&a; printf ("%d",*p); } 表示指针变量 p 取得了整型变量 a 的地址。printf("%d",*p)语句表示输出变量 a 的值。 2. 指针变量的运算 1) 赋值运算:指针变量的赋值运算有以下几种形式