第8章 指针
【练习8-1】如果有定义”int m, n = 5, *p = &m;”与m = n等价的语句是 B 。 A.m = *p; B. *p = *&n; C. m = &n; D. m = **p; 解答:
A:p是指向m的指针变量,所以*p等价于m。即m=m。
B:&n是n的地址,*&n是n的值,即把n的值赋给p指向的值m。即m=n。 C:&n是n的地址。即把n的地址赋给m。
D:**p是指p指向的指针所指向的值,在此无意义。 故选B。
【练习8-2】调用函数求两个数的和与差:计算输入的两个数的和与差,要求自定义一个函数sum_diff(float op1,float op2, float *psum, float *pdiff),其中op1和op2是输入的两个数,*psum 和*pdiff 是计算得出的和与差。 解答: #include<>
void sum_diff(float op1,float op2,float *psum,float *pdiff); int main(void) {
float op1,op2,sum,diff;
printf(\ scanf(\ sum_diff(op1,op2,&sum,&diff);
printf(\
return 0; }
void sum_diff(float op1,float op2,float *psum,float *pdiff) {
*psum=op1+op2; *pdiff=op1-op2; }
【练习8-3】两个相同类型的指针变量能不能相加为什么 解答: 不能。因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地址相加并不能保证结果为一个有效的地址值,因而在 C 语言中指针变量相加是非法的。
【练习8-4】根据表 所示,这组数据的冒泡排序其实循环到第 6 遍(即n-2)时就已经排好序了,说明有时候并不一定需要 n-1 次循环。请思考如何改进冒泡排序算法并编程实现(提示:当发现一遍循环后没有数据发生交换,说明已经排好序了)。 解答:
设置一个标志变量 flag,进入一轮循环前设置为 0,在循环中有发生数据交换就改写flag 值为 1。当该轮循环结束后检查 flag 值,如果变为 1 说明发生了数据交换,还没有排好序,如果为 0 说明没有发生交换,已经排好序。 #include<>
void bubble (int a[],int n); int main(void) {
int n,i,a[8];
printf(\ scanf(\
printf(\ for(i=0;i scanf(\ bubble(a,n); printf(\ for(i=0;i printf(\ return 0; } void bubble(int a[], int n) { int i,j,temp,flag; for(i=1;i for(j=0;j if(a[j]>a[j+1]){ temp=a[j]; a[j]=a[j+1]; a[j+1]=temp; flag=1; } if(flag==0) break; } } 【练习8-5】重做例 8-9,要求使用选择排序算法。 解答: #include<> void bubble(int a[], int n); int main(void) { int i,n,a[8]; printf(\ scanf(\ printf(\ for(i=0;i scanf(\ bubble(a,n); printf(\ for(i=0;i printf(\ return 0; } void bubble(int a[],int n) { int i,j,temp,index; for(i=0;i for(j=i+1;j 电码加密 【练习8-6】在使用scanf( )函数时,输入参数列表需要使用取地址操作符&,但当参数为字符数组名时并没有使用,为什么如果在字符数组名前加上取地址操作符&,会发生什么 解答: 因为字符数组名的值是一个特殊的固定地址,可以看作是常量指针,因此不需要再使用取地址符来获取该数组的地址。如果在字符数组名 str 前加上取地址操作符&,那么对其取地址&str 可以看做是这个数组的第一个元素的地址,由于数组地址和数组第一个元素的地址相同,所以&str 表示地址值和 str 表示的地址值是相等的。对 scanf()的变长参数列表的话,编译器只负责参数传递,怎么解释后边的几个地址的含义,是由前边的字符串确定的。所以使用scanf(“%s”,str)和scanf(“%s”,&str)都能通过编译且正常执行。 【练习8-7】 C 语言不允许用赋值表达式直接对数组赋值,为什么 解答: 数组名可以看作是常量指针,因为不可以对一个常量进行赋值,所以不允许用赋值表达式直接对数组进行赋值。 【练习8-8】输入一个字符串,把该字符串的前 3 个字母移到最后,输出变换后的字符串。比如输入“abcdef”,输出为“defabc”。 解答: #include<> #include<> #define MAXLINE 100 int main(void) { char line[MAXLINE],str[4]; int i; printf(\ gets(line); if(strlen(line)<3){ printf(\字符串长度小于3,不符合要求!\\n\ } for(i=0;i<3;i++) str[i]=line[i]; str[i]='\\0'; for(i=3;line[i]!='\\0';i++) line[i-3]=line[i]; line[i-3]='\\0'; strcat(line,str); printf(\ return 0; } 【练习8-9】使用动态内存分配的方法实现例 8-9 的冒泡排序。 解答: #include<> #include<> void bubble(int a[],int n); int main(void) { int n,j,*a,i,temp; printf(\ scanf(\ if((a=(int*)calloc(n,sizeof(int)))==NULL){ printf(\ exit(1); } printf(\ for(i=0;i scanf(\ bubble(a,n); printf(\ for(i=0;i void bubble(int a[],int n) { int i,j,temp; for(i=1;i 习题8 一、选择题 1.下列语句定义 x 为指向 int 类型变量 a 的指针,其中哪一个是正确的 B 。 A.int a, *x = a; B. int a, *x = &a; C.int *x = &a,a; D.int a, x = a; 以下选项中,对基本类型相同的指针变量不能进行运算的运算符是 A 。 A.+ B.- C.= D.== 3.若有以下说明,且 0<=i<10,则对数组元素的错误引用是 C 。 int a[ ] = {0,1,2,3,4,5,6,7,8,9}, *p = a,i; A.*(a+i) B.a[p-a+i] C.p+i D.*(&a[i]) 4.下列程序的输出结果是 B 。 int main(void) { int a[10] = {0,1,2,3,4,5,6,7,8,9}, *p = a+3; printf(“%d”, *++p); return 0;
C语言程序设计(第3版)何钦铭 颜 晖 第8章 指针



