1.以下程序输出结果是()
int main() {int a = 1, b = 2, c = 2, t;while (a < b < c) {t = a;a = b;b = t;c--;}printf("%d %d %d", a, b, c);
}
解析:a=1 b=2 c=2 a<b 成立 ,等于一个真值1 1<2 执行循环体 t被赋值为1 a被赋值2 b赋值1 c-- c变成1
a<b 不成立 则等于0 然后 0<c 成立 执行循环体 t被赋值为2 a赋值为1 b赋值为2 c-- c变成0
最后输入 1 2 0
2.以下程序输出结果是()
int main() {char a[] = "morming", t;int i, j = 0;for (i = 1; i < 7; i++)if (a[j] < a[i])j = i;t = a[j];a[j] = a[7];a[7] = a[j];puts(a);
}
解析:循环一开始循环时 a[0]<a[1] 成立 j赋值为1 又 a[1]<a[2] j又赋值为2 然后if语句不执行 一直循环到i=7
将a[7] "\0" 和 a[2] 交换位置 最后输出mo
3.以下程序输出结果是()
int main() {char ch[2][5] = { "693","825" }, * p[2];int i, j, s = 0;for (i = 0; i < 2; i++) p[i] = ch[i];for (i = 0; i < 2; i++)for (j = 0; p[i][j] >='0 ' && p[i][j] <= '9'; j += 2)s = 10 * s + p[i][j] - '0';printf("%d", s);}
对于
"693"
:
j = 0
:p[0][0]
是'6',符合条件,s = 10 * 0 + (6 - '0') = 6
j = 2
:p[0][2]
是'3',符合条件,s = 10 * 6 + (3 - '0') = 63
j = 4
: 越界,不再执行。对于
"825"
:
j = 0
:p[1][0]
是'8',符合条件,s = 10 * 63 + (8 - '0') = 638
j = 2
:p[1][2]
是'5',符合条件,s = 10 * 638 + (5 - '0') = 6385
j = 4
: 越界,不再执行。最终,程序输出的是
s
的值,注意s的值一直会保存的输出结果:
该程序的输出结果是
6385
4.以下程序输出结果是()
#define P 3
#define S(a) P*a*a
int main() {int ar;ar = S(3 + 5);printf("%d", ar);
}
5.以下程序输出结果是()
#define N 3
#define Y(n) ((N+1)*n)int main() {int z;z = 2 * (N + Y(5 + 1));printf("%d", z);
}
define 产量首先被替换 N被替换成3 Y(n)==》(3+1)*n)
然后我们看z = 2 * (N + Y(5 + 1)) 是怎么计算的?
N被替换成3 然后 Y(5+1) 是整体把n替换 所以z = 2*(3+(3+1)*5+1)=48 注意括号和乘法是优先计算的
6.以下程序输出结果是()
int main() {int a = 2, b = -1, c = 2;if (a < b)if (b < 0) c = 0;else c++;printf("%d", c);}
我们来看一下该代码输出什么? 3? 还是 2?
答案是2,为什么呢。在if分支语句中,但if没有加{ }时,后面只能执行一条语句;else会跟随他最近的if语句(第二个if); 因为a不小于b 则第二个if不执行 else也不执行 输出还是c=2没有变化
7.
#define SQR(X) X*X
main() { int a=16, k=2, m=1;
a/=SQR(k+m)/SQR(k+m);
printf("%d\n”,a); }
先做宏替换,把语句中的SQR(x)替换为x*x,特别注意,简单替换,不添加任何括号,替换后为:
main() { int a=16, k=2, m=1;
a/=k+m*k+m/k+m*k+m;
printf("%d\n”,a); }
现在我们来计算a值语句替换所有变量为数值:
a /= 2+1*2+1/2+1*2+1;
a /= 2+2+0+2+1;
a/=7;
除法之前a值16,而16/7=2,因此执行后a值是2,程序输出结果是2
8.执行以下语句,输出结果是 C 。
int x=2;printf(“%d”, ((x=4*5, x*5), x+20));A) 120 B) 100 C) 40 D) 20
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后⼀个表达式的结果(不是一上来看最后一个,前面的表达式要依次左往右计算,再取最后的结果)
解析:先从左往右计算,x被赋值20 ,然后取最后的结果 20+20=40
以下程序的输出结果是( )。
int main() {
char*s="12134211";int v[4]=0,0,0,0),k,i;
for(k=0;s[k];k++)
switch(s[k]) case’1’:i=0;case’2’:i=1;case’3’:i=2;case’4’:i=3;v[i]++:
for(k=0;k<4;k++)printf("%d",v[k]);
}
A.4 2 1 1B.0 0 0 8C.4 6 7 8D.8 8 8 8
本题考查switch,case语句,当k=0时,循环体成立,执行switch后表达式的值为’1’,执行case’1’,i的值为0,因为没有break语句,继续执行其后的语句,到最后一个语句时i的值为3,此时v[i]++,v[3]=1,接着执行k++后,k的值为1,当k=1时,循环成立,执行switch后的表达式的值为’2’,执行case’2’,i的值为1,因为没有break语句,继续执行其后的语句,到最后一个语句时,i的值为3,此时v[i]++,v[3]=2,接着执行k++后,k的值为2,依次下去,csse’4’也会执行,最后i的值一定为3,到v[3]=8时循环结束,而v[0]~v[2]的值一直没有变化,故选择B选项
9.
int w = 3;
int main() {int w = 10;printf("%d\n", fun(5) * w);
}
fun(int k)
{if (k == 0)return w;return(fun(k - 1) * k);
}
局部变量
w
的作用:
- 在
main
函数中,局部变量w
被定义为10
,遮蔽了全局变量w
(值为3
)。函数
fun
的定义:
fun
函数使用全局变量w
。在函数fun
的内部,变量w
指的是全局变量w
,即3
,而不是main
函数中的局部变量w
。函数
fun
的执行逻辑:
fun(5)
调用会递归地计算fun(4) * 5
,fun(4)
计算fun(3) * 4
,依此类推,直到fun(0)
。fun(0)
返回w
,即3
。因此,递归调用的计算过程是fun(0)
返回3
,然后fun(1)
返回3 * 1 = 3
,fun(2)
返回3 * 2 = 6
,fun(3)
返回6 * 3 = 18
,fun(4)
返回18 * 4 = 72
,fun(5)
返回72 * 5 = 360
。最终的输出:
fun(5)
返回360
,main
函数中计算fun(5) * w
为360 * 10 = 3600
。
int main() {int x = 023;printf("%d", --x);
}
023 是八进制 转成 十进制对应是 2*8^1+3*8^0=19 --x 则输出18
10.
int a[3][3] = { {2},{4},{6} };
int main() {int i, * p = &a[0][0];for (i = 0; i < 2; i++) {if (i == 0)a[i][i + 1] = *p + 1;else++p;printf("%d", *p);}
}
为了理解这段代码的输出,我们需要逐步分析它。
首先,初始化二维数组
a
的方式如下:int a[3][3] = { {2}, {4}, {6} };
这意味着:
a[0][0] = 2
,a[0][1] = 0
,a[0][2] = 0
a[1][0] = 4
,a[1][1] = 0
,a[1][2] = 0
a[2][0] = 6
,a[2][1] = 0
,a[2][2] = 0
接下来,我们定义一个整型指针
p
,并将其指向a[0][0]
(即2
):第一次循环 (
i = 0
):
i == 0
条件为真,因此执行a[0][1] = *p + 1;
。此时*p
的值是2
,所以:a[0][1] = 2 + 1; // a[0][1] 被赋值为 3
此时数组
a
变为:2 3 0
4 0 0
6 0 0
然后打印
*p
,此时*p
仍然是2
,所以打印2
。第二次循环 (
i = 1
):
这次
i == 1
条件为真,因此执行++p;
使得p
指向下一个元素,即a[0][1]
(此时p
指向3
)。接着打印
*p
,此时*p
的值是3
,所以打印3
。输出结果总结
在循环结束后,程序的输出将是:
23
因此,最终的输出结果是
23
。
fun(int x)
{static int a = 3;a += x;return(a);
}
int main() {int k = 2, m = 1, n;n = fun(k);n = fun(m);printf("%d", n);}
要注意静态变量a 它的值是等程序结束时才收回,所以a的值一直会保存知道程序结束;所以
一开始a = 5 然后 a变成6 最后返回 所以n=6
11.
f(int a)
{int b = 0; static c = 3;a = c++, b++;return(a);
}
int main() {int a = 2, i, k;for (i = 0; i < 2; i++)k = f(a++);printf("%d", k);
}
这个题目太多干扰的变量,直接看c就行 c是静态变量,跳出函数不会收回他的值,一开始a = c++
先赋值 后加一 然后调用两次函数 第一次 a的值为3 第二次 a的值为4
12.
fun(s, n1, n2) int* s, n1, n2;
{int i, j, t;i = n1; j = n2;while (i<j){t = *(s + i);*(s + i) = *(s + j);*(s + j) = t;}
}
int main() {int a[10] = { 1,2,3,4,5,6,7,8,9,0 }, i, * p = a;fun(p, 0, 3);fun(p, 4, 9);fun(p, 0, 9);for (i = 0; i < 10; i++)printf("%d", *(a + i));printf("\n");
}
该程序主要实现数组中元素的顺序调换 第一次函数调用就是将元素1 4 2 3调换 变成4321
第二次函数调用 将5 0 6 9 ....调换 变成098765 第三次函数调用 将整一个数组调换 最后变成567801234
13.
int main() {int a[] = { 1,2,3,4 }, i;int x = 0;for (i = 0; i < 4; i++) {sub(a, x);printf("%d", x);printf("\n");}}
sub(int* s, int y)
{static int t = 3;y = s[t]; t--;}
输出是
0 0 0 0
因为没有正确地传递x
的地址,或者在sub
函数中没有正确修改x
。请确保以下几点:
确保传递地址:在
main
函数中调用sub
时,确保使用&x
传递x
的地址。确保正确使用指针:在
sub
函数中,要确保通过解引用指针来修改y
的值。
14.
#include <stdlib.h>
#include <stddef.h>
void fun(float* p1, float* p2, float* s)
{s = (float*)malloc(1, sizeof(float));*s = *p1 + *(p2++);
}
int main() {float a[2] = { 1.1,2.2 }, b[2] = { 10.0,20.0 }, * s = a;fun(a, b, s);printf("%f", *s);
}
在
fun
函数中对s
的处理不当。将s
的值修改为指向新分配的内存,但在main
中仍然使用未更新的s
。 输出还是 1.100000
15.假设a和b为int型变量,则执行以下语句后,b的值为 __D____。
a=1;b=10; do {b-=a;a++; }while(b--<0); A.9B.-2C.-1D.8
第一次循环 b=8 不小于0 结束循环 所以b为8
16.当运行以下程序时,从键盘输入:AhaMA Aha
int main() {char s[80]; // 定义字符数组 schar c = 'a'; // 小写字母int i = 0; // 索引初始化// 输入字符串scanf("%s", s);// 遍历字符串while (s[i] != '\0') {if (s[i] == c) {s[i] = s[i] - 32; // 将小写字母转换为大写}else if (s[i] == c - 32) {s[i] = s[i] + 32; // 将大写字母转换为小写}i++; // 增加索引}// 输出结果puts(s);return 0;
}
1.要注意一个点 输入一个AhaMA Aha 中间有个空格,所以他只读到第一个空格前的内容
2.while循环的目的就是将 a和A 的大小写互换 最终输出 ahAMa
17 以下程序输出什么?
int main() {struct p{char name[9];int age;};struct p class[10] = { "John",17,"Paul",19,"Marry",18,"Adam",16 };printf("%c", class[2].name[0]);}
输出字母M 结构体的输出 . 成员变量
18.假定下列程序的可执行文件名为prg . exe,则在该程序所在的子目录下输入命令行: prg hello good<回车〉后,程序的输出结果是()
main(int argc, char *argv[ ])
{int i; if(argc〈=0) return; for(i=1; i〈argc; i++) printf(“%c", *argv[i]); }
argc
计数参数的数量,包括程序名称。输入命令prg hello good
后,argc
的值是 3(程序名、hello
和good
)。由于i
从 1 开始循环到argc - 1
,*argv[i]
将取每个参数的第一个字符。因此,输出为h
(来自hello
)和g
(来自good
),最终结果是hg
。
19.下列程序输出结果是 15
#define MIN(x,y) (x)<(y)?(x):(y)
int main() {int i, j, k;i = 10; j = 15;k = 10 * MIN(i, j);printf("%d", k);
}
解析:错误解法 先算10<15?10:15 返回 10 k=10*10=100
宏定义 是整体替换的 正确的解法: 10*10<15?10:15 100不小于15 返回15
20.以下语句定义正确的是 D
int main() {int a[1][4] = { 1,2,3,4,5 };float x[2][] = { {1},{2},{3} };long b[2][3] = { {1},{1,2},{1,2,3} };double y[][3] = { 0 };
}
语句 1 一行四列的二维数组 但是在赋值时,是五个元素,越界
语句 2 [][] 列数不能为空
语句 3 定义一个 二行三列的数组 赋值时为三行 报错
语句 4 正确
21.
这个值是基于结构体
struct test
的组成成分来计算的。具体来说,结构体struct test
包含以下几个部分:
- 一个整数类型成员
int m1
,通常占用2个字节(这取决于编译器和平台,但大多数现代编译器中,int
类型占用4个字节,但考虑到题目可能是在特定的环境下提问,我们按照2个字节来计算)。- 一个字符类型成员
char m2
,占用1个字节。- 一个浮点数类型成员
float m3
,占用4个字节。- 一个共用体
union uu
,它包含两个选项:一个字符数组char u1:ml-citation{ref="1" data="citationList"}
占用5个字节,和一个整数数组int u2:ml-citation{ref="2" data="citationList"}
占用4个字节。由于共用体中的所有成员共享同一块内存区域,因此共用体的大小取决于其最大的成员,即5个字节。根据上述分析,结构体
struct test
的总大小为:2(m1)+1(m2)+4(m3)+5(共用体)=122(m1)+1(m2)+4(m3)+5(共用体)=12个字节。因此,sizeof(struct test)的值是12
22.下列程序段不是死循环的是________。
A. int s=36; while(s); --s;
B. int i=100; while(1) {i=i%100+1; if(i>100) break;}
C. int k=0; do{++k;}while(k>=0);
D. for( ; ; );
选C 解析: C选项 不会死循环 int有个范围 加到一定的值他会变负数 最终跳出循环
有歧义的是A 我们可以观察到 while后面有个 ; 所以 --s是不会被执行的 所以构成死循环
23.A正确
Strcpy (p = a + 1, & st [4]);从st[4]到p,p="areyou"
B,a是一个字符数组的名字。这是一个地址。不能做++a
C.因为*st=“how are you”;有11个字符,包括\0,有12个字符。所以a[11]中最多只能存放11个元素 没有复制\0。最终没识别到\0 停止
D。[]不声明数组的大版本。
24.以下程序输出的结果是:
int main() {char* p1, * p2, str[50] = "xyz";p1 = "abcd";p2 = "ABCD";strcpy(str + 2, strcat(p1 + 2, p2 + 1));printf("%s", str);
}
代码存在未定义问题,在编写时最好用数组存放; 我们从做题角度去看的话,strcat函数是字符串拼接 将第二个参数拼接到第一个参数上 p2+1==>取BCD p1+2 ==>取cd 所以将BCD拼接到cd后得到 cdBCD 然后 str+2 表示 从z开始复制 最后 输出 xycdBCD
25.以下输出结果是: 6
struct abc
{int a, b, c;
};
int main() {struct abc s[2] = { {1,2,3},{4,5,6,} }; int t;t = s[0].a + s[1].b;printf("%d", t);
}
结构体 s[0] 初始化为{1,2,3} s[1] 初始化为{4,5,6} 结构体中的 a b c被赋值为 1 2 3 或者 456
当s[0].a 就是 输出 1 s[1].b 输出 5 最后 5+1 输出 6
26.
void fun(int* a, int* b)
{int* k;k = a; a = b; b = k;
}
int main() {int a = 3, b = 6, * x = &a, * y = &b;fun(x, y);printf("%d %d", a, b);
}
在C语言中,调用函数时是将实参复制一份给形参,所以无论怎么改变形参的值,都不会影响到实参,即传值调用。即使形参是指针变量,也没有改变C语言传值调用这个事实,实参指针也还是复制了一份给形参指针,无论怎么改变形参指针的内容(注意:不是形参指针所指向的内容),也不会影响实参指针的内容。但它们两个现在的值一样,即指向的是同一个内存地址,所以改变形参指针所指向的内容,也就改变了实参指针所指向的内容,C语言就是这样实现传址调用的。本题中fun()函数的形参就是两个指针,但函数中没有任何语句改变这两个指针所指向的内容,只是交换了两个参数的内容,所以该函数不会对传递给它的实参以及实参所指向的内容造成任何影响,故a,b初始化时为3,6,输出结果亦为3和6
27.下面程序的输出结果为( )。
struct st {int x;int *y;}*p; int dt[4]={10,20,30,40);struct st aa[4]={50,&dt[0],60,&dt[1],70,&dt[2],80,&dt[3]};int main( ) {p=aa;printf(“%d\n”,++p->x);printf(“%d|n”,(++p)->x);printf(“%d\n”,++(*p->y));}
A. 10 20 20
B. 50 60 21
C. 51 60 21
D. 60 70 31
解析:第1个输出语句中由于->的优先级高于++,因此先取结构体的分量x,再对x的值加1,再输出。p的初值为结构体数组aa的首地址即a[0]的地址,a[0]的x分量值为50,加1后输出51。第2个输出语句中++p被括号括起来,括号的优先级与->相同,自左至右结合,因此先对p加1,再取p所指向的元素的x分量的值。p加1后p指向数组元素a[1],a[1]的x分量的值为60,输出60。第3个输出语句中括号的优先级高于++,因此先求括号中表达式的值,又由于->的优先级高于*,所以先取p所指向的数组元素的y分量的值,p所指向的元素为a[1],y分量的值为&dt[1]。&dt[1]是一个存储单元的地址,是数组dt第2个元素的地址值,再取该存储单元中的值为20,最后对20加1,输出21。
28.以下程序输出的结果为:
main()
{int a[6],i;
for(i=1;i<6;i++)
{ a[i]=9*(i-2+4*(i>3))%5;
printf("%2d",a[i]);
}
}
A)-4 0 4 0 4 B)-4 0 4 0 3 C)-4 0 4 4 3 D)-4 0 4 4 0
解析 我们直接看 i=5的时候, 9*(5-2+4*1)%5 = 63%5=3 排除AD 然后计算i=4 9*(4-2+4)%5=54%5=4 *的优先级比%更高;
29.以下程序输出的结果为:
union myun {struct {int x, y, z;} u;int k;
} a;int main() {a.u.x = 4; a.u.y = 5; a.u.z = 6;a.k = 0;printf("%d", a.u.x);
}
在这个例子中,你先为结构体
u
的成员x
,y
,z
赋值,然后将k
赋值为 0。由于联合体的特性,赋值k
会覆盖之前的结构体成员。因此,printf("%d", a.u.x);
输出的将是一个未定义的值,因为a.u.x
的值已经被k
的赋值覆盖。具体的输出会取决于内存的状态,但通常情况下这会导致程序不按预期工作。如果你想确保能够打印出
a.u.x
的值,你应该避免给k
赋值,或者使用结构体成员,而不是联合体。
30.以下程序输出什么
#include <stdio.h>
void main()
{
union
{
unsigned char c;
unsigned int i[4];
}z;
z.i[0]=0x39;
z.i[1]=0x36;
printf("%c\n",z.c);
}
联合体的内存共享:在联合体中,所有成员共享相同的内存空间。这意味着对一个成员的赋值会影响到其他成员。
赋值过程:你将
i[0]
设置为0x39
,这实际上在内存中写入了这个值。0x39
的二进制表示是00111001
,对应的 ASCII 字符是'9'
。打印字符:当你使用
printf("%c\n", z.c);
打印z.c
的值时,程序读取的是i[0]
的低字节(0x39
),所以打印出'9'
。
31.正确的答案是()
若有代数式3ae/bc,则不正确的c语言表达式是()
A.a/b/c*e*3 B.3*a*e/b/c C.3*a*e/b*c D.a*e/c/b*3
在C语言中,表达式的计算顺序是根据运算符的优先级和结合性规则来确定的。需要确保在C语言表达式中正确地表示这个数学表达式。
选项A:
a/b/c*e*3
- 这个表达式首先计算
a/b
,然后结果除以c
,最后乘以e
和3
。这符合原数学表达式的结构。选项B:
3*a*e/b/c
- 这个表达式首先计算
3*a*e
,然后结果除以b
,最后除以c
。这也符合原数学表达式的结构。选项C:
3*a*e/b*c
- 这个表达式首先计算
3*a*e
,然后结果除以b
,最后乘以c
。这不符合原数学表达式的结构,因为在数学表达式中c
是分母的一部分,而在C语言表达式中它被错误地放在了分子的位置。选项D:
a*e/c/b*3
- 这个表达式首先计算
a*e
,然后结果除以c
,再除以b
,最后乘以3
。这也符合原数学表达式的结构。
32.已有如下定义和输入语句,若要求a1,a2,c1,c2的值分别为10,20,A和B,当从第一列开始输入数据时,正确的输入方式是( D )。(代表空格,↙代表Enter)
int a1,a2; char c1,c2;
scanf("%d%d",&a1,&a2);
scanf("%c%c",&c1,&c2);
A. 1020AB↙
B. 1020↙
C. 1020AB↙
D. 10 20AB↙
D 选项 10后有一个空格 结束 将10赋值给a1 然后输出20A 遇到字符 结束 将20赋值给a2 最后将AB 赋值c1 c2
33.下面四个选项中,均是不合法的整型常量的选项是( )。
A.--0f1 -oxffff 0011
B.-0xcdf 017 12,456
C.-018 999 5e2
D.-0x48e -068 03f
补充一条重要的知识点
整形常量:
1.十进制一般都是 12 15 21等等形式
2.八进制各位的数值只能是0-7 并且以0开头, 比如:011 015 031 044 等等
3.十六进制各位的数值只能是0-9 或者 A-F 并且以 0x开头 比如 0x11 0xfff 等等
4.e 后跟着的指数必须是整数 不能是浮点数 例如:-8e 5e3 等等
然后我们看回本题目 D选项都是不合法的整型常量 -0x48e -068和03f(不是合法的八进制)'''
34.以下程序输出的结果为 D
main(){ int x,i;for(i=1;i<=100;i++){ x=i;if(++x%2==0)if(++x%3==0)if(++x%7==0)printf("%d ",x);} }
A)39 81 B)42 84 C)26 68 D)28 70
- 循环:
for(i=1;i<=100;i++)
,遍历i
从1到100。- 自增和条件判断:
- 第一次自增
++x
:x
变为i + 1
,检查是否能被2整除。- 如果满足,再进行第二次自增
++x
:x
变为i + 2
,检查是否能被3整除。- 如果仍然满足,最后进行第三次自增
++x
:x
变为i + 3
,检查是否能被7整除。- 如果我们只查看
i + 3
满足42的倍数,实际上:
- 28:
i + 3 = 28
,即i = 25
->x = 28
- 70:
i + 3 = 70
,即i = 67
->x = 70
35.程序输出的结果是 k=8 b=-2
#include <stdio.h>int main() {int i, b, k = 0;for (i = 1; i <= 5; i++) {b = i % 2; // b = 0 (偶数) 或 1 (奇数)while (b-- >= 0) { // 当 b 为 0 或 1 时,循环体执行k++; // 计数器加 1}}printf("%d, %d", k, b); // 打印 k 和 b 的值return 0;
}
解析:看到关键的b = i%2 判断b是偶数还是奇数; 如果是奇数while循环两次 偶数循环一次 则循环一共执行8次 最终k的值为8 b=-1
36.输入3.6 2.4回车,则结果为(1.6)
main()
{
float x,y,z;
scanf("%f%f",&x,&y);
z=x/y;
while(1)
{
if (fabs(z)>1.0)
{
x=y; y=z; z=x/y;
}
else break;
}
printf("%f\n",y);
}
解析:fabs() 是绝对值函数,第一次循环 z=3.6/2.4 = 1.5
if语句满足则进入判断 x=2.4 y=1.5 z=2.4/1.5 = 1.6 进入第二次循环 x=1.5 y=1.6 z=1.5/1.6=0.93 不满足循环 最后输出 y=1.6
37.以下程序输出的结果是()
int main() {int a, b;for (a = 1, b = 1; a <= 100; a++) {if (b >= 20) break; // 如果 b >= 20,退出循环if (b % 3 == 1) { // 如果 b 除以 3 的余数为 1b += 3; // 将 b 增加 3continue; // 跳过当前迭代,继续下一次循环}b -= 5; // 否则,b 减去 5}printf("%d\n", a); // 打印 a 的值return 0;
}
解析:首先要明确for循环的执行顺序for(语句1;语句2;语句3)
循环的语法形式如下:
初始化只执行一次
循环次数主要看表达式2 一直为真就一直执行,表达式2至关重要
a=1 b=4
a=2 b=7
a=3 b=10
a=4 b=13
a=5 b=16
a=6 b=19
a=7 b=22因为是a++ 后置加一 所以最后输出 8
若二维数组a有m列,则计算任一元素a[i][j]在数组中位置的公式为:[ i*m+j-1 ]。(假设a[0][0]位于数组的第一个位置上。)
若二维数组a有m列 则a[i][j]前的元素个数为 i*m+j'
38.下面程序运行结果是( )
#include <stdio.h>int main() {char ch[7] = "12ab56";int i, s = 0;for (i = 0; ch[i] >= '0' && ch[i] <= '9'; i += 2) {s = 10 * s + (ch[i] - '0');}printf("%d\n", s);return 0;
}
A.1
B.1256
C.12ab56
D.1
2
5
6
解析: 要关注 for循环中的条件 规定了是数字字符才执行循环体 第一次循环时 ch[0] =1 符合
然后i+2 = 2 ch[2] = a 不符合数字字符 停止循环 最后执行s = 10*0+'1' -'0' =1
39.以下程序输出的结果是什么()
#include "stdio.h"int main() {char a1[5], a2[5], a3[5], a4[5];scanf("%s%s", a1, a2);gets(a3);gets(a4);puts(a1);puts(a2);puts(a3);puts(a4);
}
输入部分:
- 第一次输入是
aa bb
,由于scanf("%s%s", a1, a2);
,a1
将保存aa
,a2
将保存bb
。scanf 会以空格,回车 等等结束- 第二次输入是
cc dd
,会被gets(a3);
和gets(a4);
读取。 gets() 之以回车结束a3将cc dd都读取了输出部分:
puts(a1);
将输出aa
。puts(a2);
将输出bb
。puts(a3);
将输出cc dd
(因为gets
读取整行,包括空格)。puts(a4);
将等待输入,但由于没有再提供输入,将会导致程序挂起。
40.以下程序输出的结果是()
执行时输入:1234567
int main(){int x,y;scanf("%2d%*2d%ld",&x,&y);printf("%d",x+y);}
解析: 首先我们要理解 %2d 代表什么, 2是限制数字的位数 加入输入1234567 只能取12
printf输出又不一样,如果的位数不足;就补充空格,假如输出23 %3d 左边补充空格,补够三个
如果是 %-3d 那就右边补充空格
然后我们回到题目,scanf中的 %2d,是只取两位; %*2d表示跳过两位:34跳过,最后的%ld就是输出剩下的 567 然后12+567 = 579
41.以下程序输出的结果是
#include <stdio.h>void fun(int k) {if (k > 0) fun(k - 1);printf("%d", k);
}int main() {int w = 5; fun(w); printf("\n");
}
A.5 4 3 2 1
B.0 1 2 3 4 5
C.1 2 3 4 5
D.5 4 3 2 1 0
main()
函数中,w
被赋值为5
,然后调用fun(w)
。fun(k)
函数中,如果k
大于0
,就递归调用fun(k - 1)
。- 当
k
递减到0
时,不再进行递归,开始打印k
的值。输出过程
fun(5)
-> 调用fun(4)
fun(4)
-> 调用fun(3)
fun(3)
-> 调用fun(2)
fun(2)
-> 调用fun(1)
fun(1)
-> 调用fun(0)
fun(0)
-> 不再递归,打印0
- 然后依次返回并打印
1
,2
,3
,4
,5
最终输出
因此,程序的输出结果是:
012345
42.输出结果是
long fun(int n) {long s;if (n == 1 || n == 2)s = 2;elses = n + fun(n - 1);return s;
}
int main() {printf("%ld", fun(4));
}
这个程序定义了一个递归函数
fun
,计算从 1 到n
的和。我们来逐步分析一下这个函数的行为。
- 如果
n
是 1 或 2,返回 2。- 对于其他情况(
n > 2
),返回n
加上fun(n - 1)
的结果。具体来看
fun(4)
:
fun(4)
调用fun(3)
,并计算4 + fun(3)
。fun(3)
调用fun(2)
,并计算3 + fun(2)
。fun(2)
返回 2(因为n == 2
)。现在我们可以逐步计算:
fun(2)
返回 2。fun(3)
计算为3 + fun(2) = 3 + 2 = 5
。fun(4)
计算为4 + fun(3) = 4 + 5 = 9
。因此,最终在
main
函数中调用printf("%ld", fun(4));
将输出结果为 9。
43下列程序输出结果是()
#include <stdio.h>void add() {int x = 0;static int y = 0;printf("%d %d\n", x, y);x++; y = y + 2;
}int main() {int i;for (i = 0; i < 2; i++)add();return 0;
}
解析: 先分析主函数中的for循环 循环两次,调用两次add()函数; 然后我们看到add()函数,y是静态变量 他会一直保存的值直到程序结束,一开始 输出 x=0 y =0 ;然后y的值变成2;第二次循环x还是等于0 y=2 所以输出结果是
0 0
0 2
44.下列程序输出结果是()
#include <stdio.h>long fib(int n) {if (n > 2)return (fib(n - 1) + fib(n - 2)); // 应该是加号elsereturn 2;
}int main() {printf("%ld\n", fib(3)); // 使用 %ld 来打印 long 类型return 0;
}
解析
fib
函数:
- 当
n > 2
时,函数会递归调用fib(n - 1)
和fib(n - 2)
。- 当
n <= 2
时,函数返回2
。计算
fib(3)
:
fib(3)
调用:
- 由于
3 > 2
,执行fib(2) + fib(1)
。计算
fib(2)
:
fib(2)
返回2
(因为2 <= 2
)。计算
fib(1)
:
fib(1)
返回2
(因为1 <= 2
)。最终计算:
fib(3) = fib(2) + fib(1) = 2 + 2 = 4
45.要求函数的功能是交换x 和y 中的值,且通过正确调用返回交换结果.能正确执行能的函数是 。
A.funa (int *x,int *y) { int *p; *p=*x; *x=*y;*y=*p; }
B.fund (int x,int y) { int t; t=x;x=y;y=t; }
C.func (int *x,int *y) { *x=*y;*y=*x;}
D.fund (int *x,int *y) { *x=*x *y;*y=*x-*y;*x=*x-*y; }
解析:
A选项 应该修改成 int p 而不是*p
B选项只是形参发生变化,最终不改变实参的值
C这个函数会导致问题,因为第二行会把
*y
的新值覆盖了*x
的原值,最终*x
和*y
都会变成同一个值。错误。D这个函数实现了交换,不使用临时变量,而是通过数学运算来交换
*x
和*y
的值。可以正常工作。正确。
46.分析下面函数,以下说法正确的是__D____。
swap(int *p1,int *p2) { int *p; *p=*p1; *p1=*p2; *p2=*p; }
A. 交换 *p1 和 *p2 的值 B. 正确,但无法改变 *p1 和 *p2 的值 C. 交换 *p1 和 *p2 的地址 D. 可能造成系统故障,因为使用了空指针
47.若有说明:long *p,a;则不能通过scanf语句正确给输入项读入数据的程序段是______。 A.*p=&a;scanf("%ld",p); B.p=&a;scanf("%ld",p); C.scanf("%ld",p=&a); D.scanf("%ld",&a);
A 的p中是数值 不能进行争取输入,其他都正确
48.若已定义:int a[9],*p=a;并在以后的语句中未改变p的值,不能表示a[1]地址的表达式是 _______。 A.p+1 B.a+1 C.a++D.++p
C.选项只是常量的自增 不能表示a[1]地址
49.设P1和P2是指向同一个int型一维数组的指针变量,k为int型变量,则不能正确执行的语句是( )
A. P2=k; B. P1=P2; C. k=*P1+*P2; D. k=*P1*(*P2);
A选项 k是整形变量 赋值给 指针变量 会发生类型错误
50.程序输出数组中的最大值,由s指针指向该元素,则划线处条件应该是___B____。
int main(void) { int a[ 10] ={6,7,2,9,1,10,5,8,4,3,}, *p,*S;for(p=a,s=a; p-a<10; p )if(___)s=p;printf( "The max:%d",* S);return 0;
A. p>s B. *p>*S C. a[p]>a[ s] D. p-a>p-s
A.
p > s
这个条件并不能用来判断大小,因为p
和s
是指针,它们的比较只会比较地址,而不是它们所指向的值。B.
*p > *S
这个条件比较p
所指向的元素和s
所指向的元素的大小。如果*p
(当前数)大于*s
(当前最大值),那么更新s
为p
。这是一个合理的选择,因为我们想要找到最大的元素。C.
a[p] > a[s]
这个条件不正确,因为p
和s
是指针,而a[p]
和a[s]
的使用是错误的,应该用*p
和*s
来进行比较。D.
p - a > p - s
这个条件也不对,这个表达式只是计算指针之间的差值,无法用于判断大小。
51.若有说明int i,j=2,*p=&i;,则能完成i=j赋值功能的语句是______。
A.i=*p
B.*p=*&j
C.i=&j
D.i=**p;
解析:选B *是解引用操作 &取地址 ,以为i的地址指向了指针变量p *p就是i, 而*&j就是j; * 和 &可以理解成一个相反的操作 所以* & 就等于没做操作
52.以下函数的功能是()
sss(char*s,char*t){while((*s)&&(*t)&&(*t ==*s ));return(*s-*t);}
A.求字符串的长度
B.比较两个字符串的大小
C.将字符串s复制到字符串t中
D.将字符串s接续到字符串t中
解析:比较字符串的大小,返回值当*s-*t正数的时候,表示s大于t;等于0,表示相等,小于零表示s<t
53.函数的功能是______。
int fun1(char *x)
{
char *y=x;
while(*y++);
return(y-x-1);
}
A. 求字符串的长度
B. 比较两个字符串的大小
C. 将字符串x复制到字符串y
D. 将字符串x连接到字符串y后面
解析:A正确,y-x-1 表示 字符串长度 再减去1是减掉'\0'
54.输出的结果是(10)
int fun(int a, int b) {int c;c = a + b;return c;
}
int main() {int x = 5, z;z = fun(++x, --x);printf("%d", z);
}
解析:我们重点关注 ++x --x 先执行++x 变成6 然后 --x 变4 传过去 最后结果为10
55.
int main() {int i, a[10] = { 1,3,5,7,9,2,4,6,8,0 }, temp;temp = a[9];for (i = 9; i; i--)a[i] = a[i - 1];a[0] = temp;printf("a:");for (i = 0; i < 10; i++)printf("%d", a[i]);
}
- 初始化数组
a
为{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }
。temp = a[9]
将temp
设置为0
(数组最后一个元素)。for (i = 9; i; i--)
循环从索引 9 开始到 1(因为i
为非零时继续循环),在每次迭代中,a[i]
被赋值为a[i - 1]
。这会使得数组中的所有元素都向右移动一位,最后一个元素(a[9]
)将被覆盖。- 数组的变化过程如下:
- 初始:
{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }
- 移动后:
a[9]
=a[8]
=>{ 1, 3, 5, 7, 9, 2, 4, 6, 8, 8 }
a[8]
=a[7]
=>{ 1, 3, 5, 7, 9, 2, 4, 6, 6, 8 }
a[7]
=a[6]
=>{ 1, 3, 5, 7, 9, 2, 4, 4, 6, 8 }
a[6]
=a[5]
=>{ 1, 3, 5, 7, 9, 2, 2, 4, 6, 8 }
a[5]
=a[4]
=>{ 1, 3, 5, 7, 9, 9, 2, 4, 6, 8 }
a[4]
=a[3]
=>{ 1, 3, 5, 7, 7, 9, 2, 4, 6, 8 }
a[3]
=a[2]
=>{ 1, 3, 5, 5, 7, 9, 2, 4, 6, 8 }
a[2]
=a[1]
=>{ 1, 3, 3, 5, 7, 9, 2, 4, 6, 8 }
a[1]
=a[0]
=>{ 1, 1, 3, 5, 7, 9, 2, 4, 6, 8 }
- 最后,将
temp
的值(0)赋给a[0]
,所以最终数组变为:
- 最终:
{ 0, 1, 3, 5, 7, 9, 2, 4, 6, 8}
56.
#include <stdio.h>
void main()
{char c1, c2, c3, c4, c5, c6;scanf("%c%c%c%c", &c1, &c2, &c3, &c4);c5 = getchar();c6 = getchar();putchar(c1);putchar(c2);printf("%c%c\n", c5, c6);}
结果程序运行后,若从键盘输入(从第1列开始)
123<回车>
45678<回车>
则输出结果是(D)。
A.1267
B.1256
C.1278
D.1245
解析:一开始输入1 2 3 分别存到 c1 c2 c3 然后\n(回车)存到c4 然后4 存到c5 5存到c6
所以最后输出 1245
57.
#include <stdio.h>int main() {char p[] = { 'a', 'b', 'c' };char q[] = "abc";printf("%d %d", sizeof(p), sizeof(q));
}