二、程序分析
1.main()
{ char str[]="1234567";
int i;
for(j=0;i<7;i十=3)
printf("%s\n",str+i);
}
【解析】分析份循环语句可知,控制变量 i的值只能依次等于0、3、6。再分析输出语句中的输出格式,这是字符串格式,要求输出表达式是存放字符串的首地址。而输出表达式是“str+i”。我们针对i不同值来-一分析:i=0,str+0就是str,其中存放的字符串是“1234567”,所以第1行上的输出就是:1234567。当 i=3时,str+3,代表了数组元素str[3]的地址,从这儿开始的字符率串是“4567”,所以第2行输出的是:4567。同样道理,i=6时, str+6是元素str[6]的地址,从该地址存放的字符率是"7",所以第3行输出的是:7。
【参考答案】 1234567
4567
7
2.struct a{ char name[10];
int age;
}aa[3]={{"abc",20},{"def",21},{"ghi",22}};
main()
{ struct a *paa=aa;
printf("%c%c%c",(*(paa+1)).name[0]
(*paa++).name[1]
(*(paa+1)).name[2]);
}
【解析】本程序并不复杂,关键在于如何使用指向结构型数组的指针变量来引用该数组元素,以及如何引用结构型成员是数组的数组元素。
首先看结构型a及对应数组aa的定义和赋予的初值。
结构型a共有两个成员,一个是字符型数组name,另一个是整型age。
结构型数组aa有3个元素,所赋予的初值如下:
aa[0].name="abc" aa[0].age=20
aa[1].name="def" aa[1].age=21
aa[2].name="ghi" aa[2].age=22
主函数中的第1个语句是定义结构型指针变量paa,并且使它指向结构型数组aa的首地址。注意,此后的*paa就是aa[0],*(paa+i)就是aa[i]。
现在可以分析输出语句了。输出格式是3个字符格式,按照printf()函数的规定,表达式表中表达式计算顺序是自右向左进行的,下面依次讨论这3个字符格式对应的输出表达式。
第3个输出表达式是“(*(paa十1)).name[2]",其中的“*(paa+1)”代表“aa[1]”,所以该表达式就是“aa[1].name[2]”,对应的字符是'f'。
第 2个输出表达式是"(*paa++).name[1]”,其中“*ppa++”的“*”和“++”是同级运算符,结合性是自右向左的,所以“++”先计算,由于是后缀,所以要先计算“*paa”,它代表“aa[0]”,所以该表达式就是“aa[0].name[1]”,对应的字符是'b'。注意,最后要对paa进行“++”运算,使其指向aa[1]。
第 1个输出表达式是“(*(paa+1)).name[0]”,注意现在的paa以及指向aa[1]了,所以其中的“*(paa+1)”代表“aa[2]”,所以该表达式就是“aa[2].name[0]”,对应的字符是'g'。
现在可以得出结论:程序的输出是 3个字符:gbf
【参考答案】gbf
3.main()
{ int x1,x2,x3,x4;
x1=x2=x3=x4=1;
switch(x1)
{ case 1:switch(x2)
{ case 0:x3++;break;
case 1:x4--;
}
case 2:x3++,x4--;
}
printf("%d%d",x3,x4);
}
【解析】本题的关键是嵌套的多分支语句switch。注意在执行switch语句前,变量x1、x2、x3、x4已经赋值,他们的值均为1。执行外层switch语句时,用于控制分支选择的变量x1的值为1,所以要执行的是“case 1”的分支。该分支又是一个switch语句,用于控制分支选择的变量x2的值为1,所以需要执行的是“case 1”的分支。该分支执行的语句是“x4--”,使得x4的值变为0。接着退出该分支,即退出内层的switch语句。由于外层的switch语句的“case 1”分支中没有“break”语句,所以将继续执行其后的“case 2”分支,即执行“x3++,x4--;”,结果x3等于2, x4等于-1。再退出外层switch语句,执行输出语句,此时,变量x3的值为2;变量x4的值为-1。所以输出结果是2-1。
【参考答案】2-1。
4.conv(b)
int b;
{ if(b>=2)conv(b/2);
printf("%d",b%2);
return;
}
main()
{ int d;
scanf("%d",&d);
conv(d);
}
说明:本程序执行时从键盘上输入:22后跟回车键。
【解析】主函数中输入整数22存入变量d中,然后调用函数。conv()。此时将把实参d中的22传递给形参b。然后再执行函数体,函数体中前面一条语句是单分支语句,当b>=2时再用“b/2”调用自己,显然这是一个递归调用的函数。下面我们来详细分析递归调用的过程:
第1次调用函数(b=22),满足条件,引起第2次调用自己(b/2=11)
第2次调用函数(b=11),满足条件,引起第3次调用自己(b/2=5)
第3次调用函数(b=5),满足条件,引起第4次调用自己(b/2=2)
第4次调用函数(b=2),满足条件,引起第2次调用自己(b/2=1)
第5次调用函数(b=1),不满足条件,执行输出语句,输出结果为 b%2=1%2=1
执行第5次调用的返回,执行第今次调用时的输出语句,输出结果为b%2=2%2=0
执行第4次调用的返回,执行第3次调用时的输出语句,输出结果为b%2=5%2=1
执行第3次调用的返回,执行第2次调用时的输出语句,输出结果为b%2=11%2=1
执行第2次调用的返回,执行第1次调用时的输出语句,输出结果为b%2=22%2=0
执行第1次调用的返回,将返回主函数,结束程序的运行。
所以程序运行的输出结果是:10110。
【参考答案】10110。
5.void f(p1,p2)
int *p1,*p2;
{ int i,j;
*p2=0;
for(i=0;i<3;i++)
for(j=i;j<3;j++)
*p2+=*(pl+i*3+j);
return;
}
main()
{ int a[3][3]={{1,2},{3,4},{5,6}};
int s;
f(a,&s);
printf("%d",s);
}
【解析】本程序是由一个无返回值的函数f()和主函数组成的。先看主函数,定义了一个3行3列的二维数组a,并且给a赋了初值,初值如下:
a[0][0]=1 a[0][1]=2 a[0][2]=0
a[1][0]=3 a[1][1]=4 a[1][2]=0
a[2][0]=5 a[2][1]=6 a[2][2]=0
接着调用无返回值的函数f(),然后输出变量s中的值,显然这个s中的值是在函数f()中获得的。
接下来分析函数f()。该函数有两个形参,第1个形参是指针变量p1,对应的实际参数是数组a的首地址,即调用该函数后,指针变量p1是指向二维数组a的首地址。第2个形参也是指针变量p2,对应的实参是变量s的地址,即函数调用后指针变量p2是指向变量s的。再来分析函数体。前面定义了两个变量i和j,从后面的循环语句中看出是二重循环的控制变量。接着,通过“*p2=0”,给变量s赋值0。二重for循环的循环体是“*p2+=*(p1+i*3+j)”,其中的“*p2”是代表变量s的,“*(p1+i*3+j)”是代表数组元素a[i][j],这个赋值语句是把a[i][j]加到变量s中(即求数组元素的和)。现在只要分析清楚二重循环是对哪些数组元素进行求和的就可以得出变量s的值了。
下面是对二重循环的执行记录:
i=0 j=0 对应a[0][0],其值为1
j=1 对应a[0][1],其值为2
j=2 对应a[0][2],其值为0
i=1 j=1 对应a[1][1],其值为4
j=2 对应a[1][2],其值为0
i=2 j=2 对应a[2][2],其值为0
所以,s=a[0][0]+a[0][l]+a[0][2]+a[1][1]+a[2][2]+a[2][2]= 1+2+0+4+0+0=7。
【参考答案】7
6. main()
{ int i,a[5];
for(i=0;i<<5;i++)
a[i]=9*(i-2+4*(i>2))%5;
for(i=4;i>=0;i--)
printf("=",a[i]);
}
【分析】我们可以按照程序中语句执行的顺序,记录各个变量及数组元素值的方法来解决这种阅读程序写运行结果的问题。首先执行第1个for循环。
i=0, i<5的条件成立,执行循环体。
a[0]=9*(0-2+4*(0>2))%5=9*(-2)%5=-18%5=-3
i=1,1<5的条件成立,执行循环体。
a[1]=9*(1-2十4*(1>2))%5=9*(-1)%5=-9%5=-4
1=2,i<5的条件成立,执行循环体。
a[2]=9*(2-2十4*(2>2))%5=9*(0)%5=0%5=0
i=3,i<5的条件成立,执行循环体。
a[3]=9*(3-2+4*(3>2))%5=9*(5)%5=45%5=0
1=4,1<5的条件成立,执行循环体。
a[4]=9*(4-2+4*(4>2))%5=9*(6)%5=54%5=4
i=5,1<5的条件不成立,退出第1个for循环。
注意,计算中的“i>2”是关系运算,结果只能为1或0;“x%5”是模运算,结果是x除5的余数,且余数的符号和x符号相同。
再执行第2个for循环。
i=4,i>=0的条件成立,执行循环体。输出数组元素a[4]的值,等于4
i=3,i>=0的条件成立,执行循环体。输出数组元素a[3」的值,等于0
i=2,1>=0的条件成立,执行循环体。输出数组元素a[2」的位,等于0
i=1,i>=0的条件成立,执行循环体。输出数组元素a[1]的值,等于-4
i=0,1>=0的条件成立,执行循环体。输出数组元素a[0]的值,等于-3
i=-1,i>=0的条件不成立,退出第2个for循环。
【参考答案】 4 0 0 -4 -3
7.main()
{ char s[][6]={”1234”,”56789”},*p[2];
int i,sum=0;
p[0]=s[0],p[1]=s[1];
for(i=0;p[0][i」!=’\0’;i++,i++)
sum=10*sum+p[0][i]-’0’;
for(i=1;p[1]「i」!=’\0’;i++,i++)
sum=10*sum+p[1][i]-’0’;
printf("%d",sum);
}
【解析】本程序的第1条语句是定义2行5列的二维字符型数组s,并且赋了初值如下:
s[0][0]='1's[0][1]='2's[0][2]='3's[0][3]='4's[0][4]='\0'
s[1][0]='5's[1][1]='6's[1][2]='7's[1][3]='8's[1][4]='9'S[1][5]='\0'
此外还定义了字符型指针数组p,利用第3条语句赋了值,结果如下:
p[0]指向以“s[0][i]”为数组名的一维数组首地址,即p[0][i]就相当于s[0][i]
p[1]指向以“s[1][i]”为数组名的一维数组首地址,即p[1][i]就相当于s[1][i]
第2条语句定义了整型变量i(用于单重循环的控制变量)和sum,并对sum清0。
第4条语句是for循环,控制变量i初值为0,每次加2,控制循环的条件是“p[0」[i]!='\
0',注意其中的“p[0][i]”就是“s[0][i]”,这个控制循环的条件可以理解为“二维字符型数组元素s[0][i]不是字符串的结束标记则继续循环”。从控制变量i的取位来看,二维字符型数组元素只能取s[0][0]、s[0][2],因为下一个数组元素是s[0][4],该元素值是'\0'。再分析循环体中的语句,其中“ p[0][i]-'0'”是将数组元素s[0][i]中存放的数组字符减去'0',结果将是该数字字符对应的一位整数,整个语句是将sum变量中的原值乘以10以后再加上当前的数字。循环结束后的sum值就是s[0」[0」和s[0][2]中的两个数字组成的2位十进制数,结果为13。
按照同样的道理,可以分析出第2个for循环作用是完全相同的,它是把s[1」[1」、s[1][3]中的两个数字(前者为6,后者为8)拼接到sum的原值中,结果sum中值为十进制整数1368。程序的最后一个语句就是输出变量sum中的整数值。
【参考答案】 1368
8.int p(m,n)
int m,n;
{ int i,pp;
for(i=pp=1;i
PP*= m;
return(pp);
}
main()
{ printf("%d"、 p(3,4));
}
【解析】主函数中只有一条输出语句,输出结果是函数调用“p(3,4)”的返回值。所以本题的关键是函数p的功能。
分析函数p(),有两个参数m、n。函数体中关键的是for循环语句。分析这个循环语句可以看出,控制变量是i,初值为1;,终值为n,每次循环i加1。所以是标准的次数型循环,共计循环n次。循环体中是将参数m的值乘到变量pp中,变量pp在开始循环时已经设置初值为1,所以整个循环是将n个m乘到pp中。显然循环语句的功能是计算m”。而函数的返回值正是这个变量pp中的值。
由此分析可知,函数调用“p(3,4)”的返回值就是34。结果为 81,也就是本程序的输
出结果。
【参考答案】81
相关推荐:
北京 | 天津 | 上海 | 江苏 | 山东 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
广东 | 河北 | 湖南 | 广西 | 河南 |
海南 | 湖北 | 四川 | 重庆 | 云南 |
贵州 | 西藏 | 新疆 | 陕西 | 山西 |
宁夏 | 甘肃 | 青海 | 辽宁 | 吉林 |
黑龙江 | 内蒙古 |