二、程序分析
1.main()
{ char str[]="1234567";
int i;
for(j=0;i<7;i十=3)
printf("%s\n",str+i);
}
【解析】分析份循環(huán)語(yǔ)句可知,控制變量 i的值只能依次等于0、3、6。再分析輸出語(yǔ)句中的輸出格式,這是字符串格式,要求輸出表達(dá)式是存放字符串的首地址。而輸出表達(dá)式是“str+i”。我們針對(duì)i不同值來(lái)-一分析:i=0,str+0就是str,其中存放的字符串是“1234567”,所以第1行上的輸出就是:1234567。當(dāng) i=3時(shí),str+3,代表了數(shù)組元素str[3]的地址,從這兒開始的字符率串是“4567”,所以第2行輸出的是:4567。同樣道理,i=6時(shí), 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]);
}
【解析】本程序并不復(fù)雜,關(guān)鍵在于如何使用指向結(jié)構(gòu)型數(shù)組的指針變量來(lái)引用該數(shù)組元素,以及如何引用結(jié)構(gòu)型成員是數(shù)組的數(shù)組元素。
首先看結(jié)構(gòu)型a及對(duì)應(yīng)數(shù)組aa的定義和賦予的初值。
結(jié)構(gòu)型a共有兩個(gè)成員,一個(gè)是字符型數(shù)組name,另一個(gè)是整型age。
結(jié)構(gòu)型數(shù)組aa有3個(gè)元素,所賦予的初值如下:
aa[0].name="abc" aa[0].age=20
aa[1].name="def" aa[1].age=21
aa[2].name="ghi" aa[2].age=22
主函數(shù)中的第1個(gè)語(yǔ)句是定義結(jié)構(gòu)型指針變量paa,并且使它指向結(jié)構(gòu)型數(shù)組aa的首地址。注意,此后的*paa就是aa[0],*(paa+i)就是aa[i]。
現(xiàn)在可以分析輸出語(yǔ)句了。輸出格式是3個(gè)字符格式,按照printf()函數(shù)的規(guī)定,表達(dá)式表中表達(dá)式計(jì)算順序是自右向左進(jìn)行的,下面依次討論這3個(gè)字符格式對(duì)應(yīng)的輸出表達(dá)式。
第3個(gè)輸出表達(dá)式是“(*(paa十1)).name[2]",其中的“*(paa+1)”代表“aa[1]”,所以該表達(dá)式就是“aa[1].name[2]”,對(duì)應(yīng)的字符是'f'。
第 2個(gè)輸出表達(dá)式是"(*paa++).name[1]”,其中“*ppa++”的“*”和“++”是同級(jí)運(yùn)算符,結(jié)合性是自右向左的,所以“++”先計(jì)算,由于是后綴,所以要先計(jì)算“*paa”,它代表“aa[0]”,所以該表達(dá)式就是“aa[0].name[1]”,對(duì)應(yīng)的字符是'b'。注意,最后要對(duì)paa進(jìn)行“++”運(yùn)算,使其指向aa[1]。
第 1個(gè)輸出表達(dá)式是“(*(paa+1)).name[0]”,注意現(xiàn)在的paa以及指向aa[1]了,所以其中的“*(paa+1)”代表“aa[2]”,所以該表達(dá)式就是“aa[2].name[0]”,對(duì)應(yīng)的字符是'g'。
現(xiàn)在可以得出結(jié)論:程序的輸出是 3個(gè)字符: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);
}
【解析】本題的關(guān)鍵是嵌套的多分支語(yǔ)句switch。注意在執(zhí)行switch語(yǔ)句前,變量x1、x2、x3、x4已經(jīng)賦值,他們的值均為1。執(zhí)行外層switch語(yǔ)句時(shí),用于控制分支選擇的變量x1的值為1,所以要執(zhí)行的是“case 1”的分支。該分支又是一個(gè)switch語(yǔ)句,用于控制分支選擇的變量x2的值為1,所以需要執(zhí)行的是“case 1”的分支。該分支執(zhí)行的語(yǔ)句是“x4--”,使得x4的值變?yōu)?。接著退出該分支,即退出內(nèi)層的switch語(yǔ)句。由于外層的switch語(yǔ)句的“case 1”分支中沒有“break”語(yǔ)句,所以將繼續(xù)執(zhí)行其后的“case 2”分支,即執(zhí)行“x3++,x4--;”,結(jié)果x3等于2, x4等于-1。再退出外層switch語(yǔ)句,執(zhí)行輸出語(yǔ)句,此時(shí),變量x3的值為2;變量x4的值為-1。所以輸出結(jié)果是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);
}
說(shuō)明:本程序執(zhí)行時(shí)從鍵盤上輸入:22后跟回車鍵。
【解析】主函數(shù)中輸入整數(shù)22存入變量d中,然后調(diào)用函數(shù)。conv()。此時(shí)將把實(shí)參d中的22傳遞給形參b。然后再執(zhí)行函數(shù)體,函數(shù)體中前面一條語(yǔ)句是單分支語(yǔ)句,當(dāng)b>=2時(shí)再用“b/2”調(diào)用自己,顯然這是一個(gè)遞歸調(diào)用的函數(shù)。下面我們來(lái)詳細(xì)分析遞歸調(diào)用的過(guò)程:
第1次調(diào)用函數(shù)(b=22),滿足條件,引起第2次調(diào)用自己(b/2=11)
第2次調(diào)用函數(shù)(b=11),滿足條件,引起第3次調(diào)用自己(b/2=5)
第3次調(diào)用函數(shù)(b=5),滿足條件,引起第4次調(diào)用自己(b/2=2)
第4次調(diào)用函數(shù)(b=2),滿足條件,引起第2次調(diào)用自己(b/2=1)
第5次調(diào)用函數(shù)(b=1),不滿足條件,執(zhí)行輸出語(yǔ)句,輸出結(jié)果為 b%2=1%2=1
執(zhí)行第5次調(diào)用的返回,執(zhí)行第今次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=2%2=0
執(zhí)行第4次調(diào)用的返回,執(zhí)行第3次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=5%2=1
執(zhí)行第3次調(diào)用的返回,執(zhí)行第2次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=11%2=1
執(zhí)行第2次調(diào)用的返回,執(zhí)行第1次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=22%2=0
執(zhí)行第1次調(diào)用的返回,將返回主函數(shù),結(jié)束程序的運(yùn)行。
所以程序運(yùn)行的輸出結(jié)果是: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);
}
【解析】本程序是由一個(gè)無(wú)返回值的函數(shù)f()和主函數(shù)組成的。先看主函數(shù),定義了一個(gè)3行3列的二維數(shù)組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
接著調(diào)用無(wú)返回值的函數(shù)f(),然后輸出變量s中的值,顯然這個(gè)s中的值是在函數(shù)f()中獲得的。
接下來(lái)分析函數(shù)f()。該函數(shù)有兩個(gè)形參,第1個(gè)形參是指針變量p1,對(duì)應(yīng)的實(shí)際參數(shù)是數(shù)組a的首地址,即調(diào)用該函數(shù)后,指針變量p1是指向二維數(shù)組a的首地址。第2個(gè)形參也是指針變量p2,對(duì)應(yīng)的實(shí)參是變量s的地址,即函數(shù)調(diào)用后指針變量p2是指向變量s的。再來(lái)分析函數(shù)體。前面定義了兩個(gè)變量i和j,從后面的循環(huán)語(yǔ)句中看出是二重循環(huán)的控制變量。接著,通過(guò)“*p2=0”,給變量s賦值0。二重for循環(huán)的循環(huán)體是“*p2+=*(p1+i*3+j)”,其中的“*p2”是代表變量s的,“*(p1+i*3+j)”是代表數(shù)組元素a[i][j],這個(gè)賦值語(yǔ)句是把a(bǔ)[i][j]加到變量s中(即求數(shù)組元素的和)?,F(xiàn)在只要分析清楚二重循環(huán)是對(duì)哪些數(shù)組元素進(jìn)行求和的就可以得出變量s的值了。
下面是對(duì)二重循環(huán)的執(zhí)行記錄:
i=0 j=0 對(duì)應(yīng)a[0][0],其值為1
j=1 對(duì)應(yīng)a[0][1],其值為2
j=2 對(duì)應(yīng)a[0][2],其值為0
i=1 j=1 對(duì)應(yīng)a[1][1],其值為4
j=2 對(duì)應(yīng)a[1][2],其值為0
i=2 j=2 對(duì)應(yīng)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。
1.main()
{ char str[]="1234567";
int i;
for(j=0;i<7;i十=3)
printf("%s\n",str+i);
}
【解析】分析份循環(huán)語(yǔ)句可知,控制變量 i的值只能依次等于0、3、6。再分析輸出語(yǔ)句中的輸出格式,這是字符串格式,要求輸出表達(dá)式是存放字符串的首地址。而輸出表達(dá)式是“str+i”。我們針對(duì)i不同值來(lái)-一分析:i=0,str+0就是str,其中存放的字符串是“1234567”,所以第1行上的輸出就是:1234567。當(dāng) i=3時(shí),str+3,代表了數(shù)組元素str[3]的地址,從這兒開始的字符率串是“4567”,所以第2行輸出的是:4567。同樣道理,i=6時(shí), 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]);
}
【解析】本程序并不復(fù)雜,關(guān)鍵在于如何使用指向結(jié)構(gòu)型數(shù)組的指針變量來(lái)引用該數(shù)組元素,以及如何引用結(jié)構(gòu)型成員是數(shù)組的數(shù)組元素。
首先看結(jié)構(gòu)型a及對(duì)應(yīng)數(shù)組aa的定義和賦予的初值。
結(jié)構(gòu)型a共有兩個(gè)成員,一個(gè)是字符型數(shù)組name,另一個(gè)是整型age。
結(jié)構(gòu)型數(shù)組aa有3個(gè)元素,所賦予的初值如下:
aa[0].name="abc" aa[0].age=20
aa[1].name="def" aa[1].age=21
aa[2].name="ghi" aa[2].age=22
主函數(shù)中的第1個(gè)語(yǔ)句是定義結(jié)構(gòu)型指針變量paa,并且使它指向結(jié)構(gòu)型數(shù)組aa的首地址。注意,此后的*paa就是aa[0],*(paa+i)就是aa[i]。
現(xiàn)在可以分析輸出語(yǔ)句了。輸出格式是3個(gè)字符格式,按照printf()函數(shù)的規(guī)定,表達(dá)式表中表達(dá)式計(jì)算順序是自右向左進(jìn)行的,下面依次討論這3個(gè)字符格式對(duì)應(yīng)的輸出表達(dá)式。
第3個(gè)輸出表達(dá)式是“(*(paa十1)).name[2]",其中的“*(paa+1)”代表“aa[1]”,所以該表達(dá)式就是“aa[1].name[2]”,對(duì)應(yīng)的字符是'f'。
第 2個(gè)輸出表達(dá)式是"(*paa++).name[1]”,其中“*ppa++”的“*”和“++”是同級(jí)運(yùn)算符,結(jié)合性是自右向左的,所以“++”先計(jì)算,由于是后綴,所以要先計(jì)算“*paa”,它代表“aa[0]”,所以該表達(dá)式就是“aa[0].name[1]”,對(duì)應(yīng)的字符是'b'。注意,最后要對(duì)paa進(jìn)行“++”運(yùn)算,使其指向aa[1]。
第 1個(gè)輸出表達(dá)式是“(*(paa+1)).name[0]”,注意現(xiàn)在的paa以及指向aa[1]了,所以其中的“*(paa+1)”代表“aa[2]”,所以該表達(dá)式就是“aa[2].name[0]”,對(duì)應(yīng)的字符是'g'。
現(xiàn)在可以得出結(jié)論:程序的輸出是 3個(gè)字符: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);
}
【解析】本題的關(guān)鍵是嵌套的多分支語(yǔ)句switch。注意在執(zhí)行switch語(yǔ)句前,變量x1、x2、x3、x4已經(jīng)賦值,他們的值均為1。執(zhí)行外層switch語(yǔ)句時(shí),用于控制分支選擇的變量x1的值為1,所以要執(zhí)行的是“case 1”的分支。該分支又是一個(gè)switch語(yǔ)句,用于控制分支選擇的變量x2的值為1,所以需要執(zhí)行的是“case 1”的分支。該分支執(zhí)行的語(yǔ)句是“x4--”,使得x4的值變?yōu)?。接著退出該分支,即退出內(nèi)層的switch語(yǔ)句。由于外層的switch語(yǔ)句的“case 1”分支中沒有“break”語(yǔ)句,所以將繼續(xù)執(zhí)行其后的“case 2”分支,即執(zhí)行“x3++,x4--;”,結(jié)果x3等于2, x4等于-1。再退出外層switch語(yǔ)句,執(zhí)行輸出語(yǔ)句,此時(shí),變量x3的值為2;變量x4的值為-1。所以輸出結(jié)果是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);
}
說(shuō)明:本程序執(zhí)行時(shí)從鍵盤上輸入:22后跟回車鍵。
【解析】主函數(shù)中輸入整數(shù)22存入變量d中,然后調(diào)用函數(shù)。conv()。此時(shí)將把實(shí)參d中的22傳遞給形參b。然后再執(zhí)行函數(shù)體,函數(shù)體中前面一條語(yǔ)句是單分支語(yǔ)句,當(dāng)b>=2時(shí)再用“b/2”調(diào)用自己,顯然這是一個(gè)遞歸調(diào)用的函數(shù)。下面我們來(lái)詳細(xì)分析遞歸調(diào)用的過(guò)程:
第1次調(diào)用函數(shù)(b=22),滿足條件,引起第2次調(diào)用自己(b/2=11)
第2次調(diào)用函數(shù)(b=11),滿足條件,引起第3次調(diào)用自己(b/2=5)
第3次調(diào)用函數(shù)(b=5),滿足條件,引起第4次調(diào)用自己(b/2=2)
第4次調(diào)用函數(shù)(b=2),滿足條件,引起第2次調(diào)用自己(b/2=1)
第5次調(diào)用函數(shù)(b=1),不滿足條件,執(zhí)行輸出語(yǔ)句,輸出結(jié)果為 b%2=1%2=1
執(zhí)行第5次調(diào)用的返回,執(zhí)行第今次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=2%2=0
執(zhí)行第4次調(diào)用的返回,執(zhí)行第3次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=5%2=1
執(zhí)行第3次調(diào)用的返回,執(zhí)行第2次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=11%2=1
執(zhí)行第2次調(diào)用的返回,執(zhí)行第1次調(diào)用時(shí)的輸出語(yǔ)句,輸出結(jié)果為b%2=22%2=0
執(zhí)行第1次調(diào)用的返回,將返回主函數(shù),結(jié)束程序的運(yùn)行。
所以程序運(yùn)行的輸出結(jié)果是: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);
}
【解析】本程序是由一個(gè)無(wú)返回值的函數(shù)f()和主函數(shù)組成的。先看主函數(shù),定義了一個(gè)3行3列的二維數(shù)組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
接著調(diào)用無(wú)返回值的函數(shù)f(),然后輸出變量s中的值,顯然這個(gè)s中的值是在函數(shù)f()中獲得的。
接下來(lái)分析函數(shù)f()。該函數(shù)有兩個(gè)形參,第1個(gè)形參是指針變量p1,對(duì)應(yīng)的實(shí)際參數(shù)是數(shù)組a的首地址,即調(diào)用該函數(shù)后,指針變量p1是指向二維數(shù)組a的首地址。第2個(gè)形參也是指針變量p2,對(duì)應(yīng)的實(shí)參是變量s的地址,即函數(shù)調(diào)用后指針變量p2是指向變量s的。再來(lái)分析函數(shù)體。前面定義了兩個(gè)變量i和j,從后面的循環(huán)語(yǔ)句中看出是二重循環(huán)的控制變量。接著,通過(guò)“*p2=0”,給變量s賦值0。二重for循環(huán)的循環(huán)體是“*p2+=*(p1+i*3+j)”,其中的“*p2”是代表變量s的,“*(p1+i*3+j)”是代表數(shù)組元素a[i][j],這個(gè)賦值語(yǔ)句是把a(bǔ)[i][j]加到變量s中(即求數(shù)組元素的和)?,F(xiàn)在只要分析清楚二重循環(huán)是對(duì)哪些數(shù)組元素進(jìn)行求和的就可以得出變量s的值了。
下面是對(duì)二重循環(huán)的執(zhí)行記錄:
i=0 j=0 對(duì)應(yīng)a[0][0],其值為1
j=1 對(duì)應(yīng)a[0][1],其值為2
j=2 對(duì)應(yīng)a[0][2],其值為0
i=1 j=1 對(duì)應(yīng)a[1][1],其值為4
j=2 對(duì)應(yīng)a[1][2],其值為0
i=2 j=2 對(duì)應(yīng)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。