C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx

上传人:b****7 文档编号:8814096 上传时间:2023-02-01 格式:DOCX 页数:22 大小:21.30KB
下载 相关 举报
C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx_第1页
第1页 / 共22页
C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx_第2页
第2页 / 共22页
C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx_第3页
第3页 / 共22页
C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx_第4页
第4页 / 共22页
C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx

《C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx》由会员分享,可在线阅读,更多相关《C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx(22页珍藏版)》请在冰豆网上搜索。

C语言程序设计第3版何钦铭 颜 晖 第8章指针.docx

C语言程序设计第3版何钦铭颜晖第8章指针

第8章指针

【练习8-1】如果有定义”intm,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(floatop1,floatop2,float*psum,float*pdiff),其中op1和op2是输入的两个数,*psum和*pdiff是计算得出的和与差。

解答:

#include

voidsum_diff(floatop1,floatop2,float*psum,float*pdiff);

intmain(void)

{

floatop1,op2,sum,diff;

printf("Inputop1andop2:

");

scanf("%f%f",&op1,&op2);

sum_diff(op1,op2,&sum,&diff);

printf("%f+%f=%f;%f-%f=%f\n",op1,op2,sum,op1,op2,diff);

return0;

}

voidsum_diff(floatop1,floatop2,float*psum,float*pdiff)

{

*psum=op1+op2;

*pdiff=op1-op2;

}

【练习8-3】两个相同类型的指针变量能不能相加?

为什么?

解答:

不能。

因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地址相加并不能保证结果为一个有效的地址值,因而在C语言中指针变量相加是非法的。

【练习8-4】根据表8.2所示,这组数据的冒泡排序其实循环到第6遍(即n-2)时就已经排好序了,说明有时候并不一定需要n-1次循环。

请思考如何改进冒泡排序算法并编程实现(提示:

当发现一遍循环后没有数据发生交换,说明已经排好序了)。

解答:

设置一个标志变量flag,进入一轮循环前设置为0,在循环中有发生数据交换就改写flag值为1。

当该轮循环结束后检查flag值,如果变为1说明发生了数据交换,还没有排好序,如果为0说明没有发生交换,已经排好序。

#include

voidbubble(inta[],intn);

intmain(void)

{

intn,i,a[8];

printf("Entern(n<=8):

");

scanf("%d",&n);

printf("Entera[%d]:

",n);

for(i=0;i

scanf("%d",&a[i]);

bubble(a,n);

printf("Aftersorted,a[%d]=",n);

for(i=0;i

printf("%3d",a[i]);

return0;

}

voidbubble(inta[],intn)

{

inti,j,temp,flag;

for(i=1;i

flag=0;

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

voidbubble(inta[],intn);

intmain(void)

{

inti,n,a[8];

printf("Entern(n<=8):

");

scanf("%d",&n);

printf("Entera[%d]:

",n);

for(i=0;i

scanf("%d",&a[i]);

bubble(a,n);

printf("Aftersorted,a[%d]=",n);

for(i=0;i

printf("%3d",a[i]);

return0;

}

voidbubble(inta[],intn)

{

inti,j,temp,index;

for(i=0;i

index=i;

for(j=i+1;j

if(a[j]

temp=a[i];

a[i]=a[index];

a[index]=temp;

}

}

8.4电码加密

【练习8-6】在使用scanf()函数时,输入参数列表需要使用取地址操作符&,但当参数为字符数组名时并没有使用,为什么?

如果在字符数组名前加上取地址操作符&,会发生什么?

解答:

因为字符数组名的值是一个特殊的固定地址,可以看作是常量指针,因此不需要再使用取地址符来获取该数组的地址。

如果在字符数组名str前加上取地址操作符&,那么对其取地址&str可以看做是这个数组的第一个元素的地址,由于数组地址和数组第一个元素的地址相同,所以&str表示地址值和str表示的地址值是相等的。

对scanf()的变长参数列表的话,编译器只负责参数传递,怎么解释后边的几个地址的含义,是由前边的字符串确定的。

所以使用scanf(“%s”,str)和scanf(“%s”,&str)都能通过编译且正常执行。

【练习8-7】C语言不允许用赋值表达式直接对数组赋值,为什么?

解答:

数组名可以看作是常量指针,因为不可以对一个常量进行赋值,所以不允许用赋值表达式直接对数组进行赋值。

【练习8-8】输入一个字符串,把该字符串的前3个字母移到最后,输出变换后的字符串。

比如输入“abcdef”,输出为“defabc”。

解答:

#include

#include

#defineMAXLINE100

intmain(void)

{

charline[MAXLINE],str[4];

inti;

printf("Inputthestring:

");

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("%s%s\n","Afterchanging:

",line);

return0;

}

【练习8-9】使用动态内存分配的方法实现例8-9的冒泡排序。

解答:

#include

#include

voidbubble(inta[],intn);

intmain(void)

{

intn,j,*a,i,temp;

printf("Entern(n<=8):

");

scanf("%d",&n);

if((a=(int*)calloc(n,sizeof(int)))==NULL){

printf("Notabletoallocatememory.\n");

exit

(1);

}

printf("Entea[%d]:

",n);

for(i=0;i

scanf("%d",a+i);

bubble(a,n);

printf("Aftersorted,a[%d]=",n);

for(i=0;i

printf("%3d",*(a+i));

free(a);

return0;

}

voidbubble(inta[],intn)

{

inti,j,temp;

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;

}

}

习题8

一、选择题

1.下列语句定义x为指向int类型变量a的指针,其中哪一个是正确的B。

A.inta,*x=a;B.inta,*x=&a;

C.int*x=&a,a;D.inta,x=a;

2.以下选项中,对基本类型相同的指针变量不能进行运算的运算符是A。

A.+B.-C.=D.==

3.若有以下说明,且0<=i<10,则对数组元素的错误引用是C。

inta[]={0,1,2,3,4,5,6,7,8,9},*p=a,i;

A.*(a+i)B.a[p-a+i]C.p+iD.*(&a[i])

4.下列程序的输出结果是B。

intmain(void)

{

inta[10]={0,1,2,3,4,5,6,7,8,9},*p=a+3;

printf(“%d”,*++p);

return0;

}

A.3B.4C.a[4]的地址D.非法

5.对于下列程序,正确的是A。

voidf(int*p)

{

*p=5;

}

intmain(void)

{

inta,*p;

a=10;

p=&a;

f(p);

printf(“%d”,(*p)++);

return0;

}

A.5B.6C.10D.11

二、填空题

1.下列函数在一维数组a中将x插入到下标为i(i>=0)的元素前。

如果i>=元素的个数,则x插入到末尾。

原有的元素个数存放在指针n所指向的变量中,插入后元素个数加1。

请填空。

voidinsert(doublea[],int*n,doublex,inti)

{

intj;

if_(i<*n)_

for(j=*n-1;_j>=i_;j--)

_a[j+1]_=a[j];

else

i=*n;

a[i]=_x_;

(*n)++;

}

2.下列程序先消除输入字符串的前后空格,再判断是否是“回文”(即字符串正读和倒读都是一样),若是则输出YES,否则输出NO。

请填空。

#include

#include

intmain(void)

{

chars[80],ch,*p,*q;

inti,j,n;

gets(s);

p=_s_;

while(*p==’’)_p++_;

n=strlen(s);

q=_s+n-1_;

while(*q==’’)_q--_;

while(_p

{

p++;

_q--_;

}

if(p

printf(“NO\n”);

else

printf(“YES\n”);

return0;

}

3.下列程序在数组中同时查找最大元素和最小元素的下标,分别存放在main()函数的fmax和min变量中。

请填空。

voidfind(int*,int,int*,int*);

intmain(void)

{

intmax,min,a[]={5,3,7,9,2,0,4,1,6,8};

find(_a,10,&max,&min_);

printf(“%d,%d\n”,max,min);

return0;

}

voidfind(int*a,intn,int*max,int*min)

{

inti;

*max=*min=0;

for(i=1;i

{

if(a[i]>a[*max])_*max=i_;

if(a[i]

}

}

4.写出下列程序的执行结果00

12

24

00

23

46

#include

intmain(void)

{

inta[10],b[10],*pa,*pb,i;

pa=a;

pb=b;

for(i=0;i<3;i++,pa++,pb++)

{

*pa=i;

*pb=2*i;

printf(“%d\t%d\n”,*pa,*pb);

}

pa=&a[0];

pb=&b[0];

for(i=0;i<3;i++)

{

*pa=*pa+i;

*pb=*pb+i;

printf(“%d\t%d\n”,*pa++,*pb++);

}

return0;

}

三、程序设计题

1.拆分实数的整数与小数部分:

要求定义一个函数voidsplitfloat(floatx,int*intpart,float*fracpart),其中x是被拆分的实数,*intpart和*fracpart分别是将实数x拆分出来的整数部分与小数部分。

编写主函数,并在其中调用函数splitfloat()。

试编写相应程序。

解答:

#include

voidsplitfloat(floatx,int*intpart,float*fracpart);

intmain(void)

{

floatx,fracpart;

intintpart;

printf("Inputanumber:

");

scanf("%f",&x);

splitfloat(x,&intpart,&fracpart);

printf("Theintpartis:

%d",intpart);

printf("Thefracpartis:

%f",fracpart);

return0;

}

voidsplitfloat(floatx,int*intpart,float*fracpart)

{

*intpart=(int)x;

*fracpart=x-*intpart;

}

2.在数组中查找指定元素:

输入1个正整数n(1

要求定义和调用函数search(intlist[],intn,intx),在数组list中查找元素x,若找到则返回相应下标,否则返回-1,参数n代表数组list中元素的数量。

试编写相应程序。

解答:

#include

intsearch(intlist[],intn,intx);

intmain(void)

{

inti,n,res,x;

inta[10];

printf("Inputn:

");

scanf("%d",&n);

for(i=0;i

scanf("%d",&a[i]);

printf("Inputx:

");

scanf("%d",&x);

res=search(a,n,x);

if(res>=0)

printf("index=%d\n",res);

else

printf("Notfound\n");

return0;

}

intsearch(intlist[],intn,intx)

{

inti;

for(i=0;i

if(list[i]==x)returni;

return-1;

}

3.循环后移:

有n个整数,使前面各数顺序向后移m个位置,移出的数再从开头移入。

编写一个函数实现以上功能,在主函数中输入n个整数并输出调整后的n个数。

试编写相应程序。

解答:

#include

voidmove(int*x,intn,intm);

intmain(void)

{

inti,m,n;

inta[80];

printf("Entern:

");

scanf("%d",&n);

printf("Enterm:

");

scanf("%d",&m);

for(i=0;i

scanf("%d",&a[i]);

move(a,n,m);

printf("Aftermove:

");

for(i=0;i

printf("%d",a[i]);

return0;

}

voidmove(int*p,intn,intm)

{

inti,j,k=0,a[80];

for(i=0;i

if(i

a[i+m]=p[i];

else

a[k++]=p[i];

for(i=0;i

p[i]=a[i];

}

4.报数:

有n个人围成一圈,按顺序从1到n编好号。

从第一个人开始报数,报到m(m

如此下去,直到留下最后一个人。

编写程序,输入整数n和m,并按退出顺序输出退出圈子的人的编号。

试编写相应程序。

解答:

#include

intmain(void)

{

intcount,i,j,m,n;

intnum[80]={0};

printf("Inputn:

");

scanf("%d",&n);

printf("Inputm:

");

scanf("%d",&m);

i=j=count=0;

while(count

if(num[i]==0)

j++;

if(j%m==0&&j){

count++;

num[i]=-1;

j=0;//报数报到m后,j重归0,开始下次报数

}

i++;//读取下一个元素

i%=n;//一次n个跟报完数,开始下一次(除余n是因为i是下标,从0开始,n是具体数//从1开始

}//i为n时下次a[0]报数)

for(i=0;i

if(num[i]==0)

printf("LastNois:

%d\n",i+1);

return0;

}

5.使用函数实现字符串复制:

输入一个字符串t和一个正整数m,将字符串中从第m个字符开始的全部字符复制到字符串s中,再输出字符串s。

要求自定义并调用函数voidstrmcpy(char*s,char*t,intm)。

试编写相应程序。

解答:

#include

#include

voidstrmcpy(char*s,char*t,intm);

intmain(void)

{

chars[80],t[80];

intm;

printf("Inputthestring:

");

gets(t);

printf("Enterm:

");

scanf("%d",&m);

if(strlen(t)

printf("ErrorInput");

return0;

}

else{

strmcpy(s,t,m);

puts(s);

}

return0;

}

voidstrmcpy(char*s,char*t,intm)

{

t=t+m-1;

while(*t!

='\0'){

*s=*t;

s++;

t++;

}

*s='\0';

}

6.删除字符:

输入一个字符串,再输入一个字符ch,将字符串中所有的ch字符删除后输出该字符串。

要求定义和调用函数delchar(s,c),该函数将字符串s中出现的所有c字符删除。

试编写相应程序。

解答:

#include

voiddelchar(char*s,charc);

intmain(void)

{

charc;

chars[80];

printf("Inputthestring:

");

gets(s);

printf("Inputach:

");

scanf("%c",&c);

delchar(s,c);

printf("result:

");

puts(s);

return0;

}

voiddelchar(char*s,charc)

{

inti,j;

i=j=0;

while(s[i]!

='\0'){

if(s[i]!

=c){

s[j]=s[i];

j++;

}

i++;

}

s[j]='\0';

}

7.字符串排序:

输入5个字符串,按由小到大的顺序输出。

试编写相应程序。

解答:

#include

#include

intmain(void)

{

intn,i,j,index;

charsx[80][80],stemp[80];

printf("Entern:

");

scanf("%d",&n);

printf("Input%dstrings:

",n);

for(i=0;i

scanf("%s",sx[i]);//每行的基地址

for(i=0;i

index=i;

for(j=i+1;j

if(strcmp(sx[j],sx[index])<0)

index=j;

strcpy(stemp,sx[i]);

strcpy(sx[i],sx[index]);

strcpy(sx[index],stemp);

}

printf("aftersorted:

\n");

for(i=0;i<5;i++)

printf("%s\t",sx[i]);

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 数学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1