计算机二级 C语言 选择题 程序题

1.

根据定义,p 是一个指向 int 的指针,现在它指向 x[1][1]  这个起始位置。

x[3][3]这个数组可以想象为一个 3x3 的网格,其中 x[0][0] 是网格的左上角元素,x[2][2] 是网格的右下角元素。数组元素按照行优先的顺序存储,即先填充第一行,然后是第二行,最后是第三行。在这个特定的数组中,x[1][1] 表示的是第二行第二列的元素,即元素5。

9         8                     7

6         5(x[1][1])    4

3         2                      1

i=0,输出p[0],也就是x[1][1],输出5。(i=1→p[1][2]→元素4)

i=2,输出p[2],也就是x[2][0],输出3。

所以结果是53.

2.

①a=0,b=5,条件为真,a++,b--
②a=1,b=4,条件为真,a++,b--
③a=2,b=3,条件为真,a++,b--
④a=3,b=2,3<2 || 'a'!='@' 条件为真,a++,b--
⑤a=4,b=1,4<1 || 'b'!='@' 条件为真,a++,b--
⑥a=5,b=0,5<0 || '@'!='@' 条件为假,输出结果

即结果是5,0
 

3.问:循环体A与循环体B的执行次数相同吗?

第一个循环结构:
这个结构首先执行一次do块内的while循环(包括其循环体A),无论条件表达式1的初始值是什么。
如果在第一次执行while(条件表达式1)循环时,条件表达式1就为假,则循环体A不会被执行。但如果为真,则循环体A会反复执行,直到条件表达式1变为假。
随后,外层do-while循环会检查条件表达式2。如果为真,则再次执行内层的while循环(包括循环体A);如果为假,则整个循环结构结束。
第二个循环结构:
这个结构首先检查条件表达式1。如果为真,则执行do-while循环(包括其循环体B),无论条件表达式2的初始值是什么。
循环体B至少会被执行一次,因为这是一个do-while循环。
然后,do-while循环内部会检查条件表达式2。如果为真,则循环体B会再次执行;如果为假,则退出内层do-while循环,但外层while循环可能会根据条件表达式1的当前值继续或结束。
结论:
在给定条件下(即条件表达式1和条件表达式2的初始值、循环体内的操作以及循环体A与B的完全相同),循环体A和循环体B的执行次数将一样。
 

4.


在 main 函数中,有一个 do-while 循环,循环三次,每次调用 fun 函数并传入 a+i 作为参数。这意味着 fun 函数将分别处理数组 a 的前四个元素(因为 i 从 0 到 2):
当 i=0 时,处理 a[0] 到 a[3],交换 a[0] 和 a[3],即 1 和 4。
当 i=1 时,处理 a[1] 到 a[4],但这里只有 a[1] 和 a[4] 之间的交换是有效的(因为 a[4] 是数组的有效元素,而 a[5] 虽然是数组的一部分但不在本次交换的考虑范围内),即 2 和 5 交换。
当 i=2 时,处理 a[2] 到 a[5],但同样只有 a[2] 和 a[5] 之间的交换是有效的,即 3 和 6 交换。
最后,打印出数组 a 的所有元素。
根据上述逻辑,数组 a 的最终状态将是 {4, 5, 6, 1, 2, 3}。

5.库函数rand()的功能是产生一个在0~32767之间的随机数。若要用此函数随机产生一个0~99.99(2位小数)之间的数,以能实现此要求的表达式是_

A.(rand ()%10000)/100.0

B.(rand()%10000)/100

C.(rand ()%9000+1000.0)/100.0

D.(rand()%100)/100.0

解析:

A. (rand() % 10000) / 100.0
rand() % 10000 产生一个0到9999之间的整数。
除以100.0后,结果是一个0.00到99.99之间的浮点数,包括两位小数,满足要求。

B. (rand() % 10000) / 100
这将产生一个整数或浮点数(取决于编程语言的整数除法行为),但通常会被截断为整数,不满足题目要求的两位小数。

C. (rand() % 9000 + 1000.0) / 100.0
rand() % 9000 产生一个0到8999之间的整数。
加上1000.0后,范围是1000.0到9999.0。
除以100.0后,结果是10.00到99.99之间的浮点数,虽然满足两位小数的要求,但不包括0.00到9.99的范围,因此不完全符合题目要求。

D. (rand() % 100) / 100.0
rand() % 100 产生一个0到99之间的整数。
除以100.0后,结果是一个0.00到0.99之间的浮点数,不包括1.00到99.99的范围,因此不满足题目要求。

综上所述,只有选项A能够产生一个0到99.99之间(包含两位小数)的随机数。

6.

主函数中,pa指向a的值,pb指向b的值。函数fun()中,pa指向的值减1,则a的值减1,得到1.5,最后按照格式输出1.500000。

7.给定定义:

int a = 3;  
int *p = &a;  
int **q = &p;

则以下叙述中错误的是

A.q是指针变量,*q就是变量a

B.p是指针变量,p指向变量a

C.q指向变量p,所以*q指向变量a

D.*p与**q都代表变量a

解析:

a 是一个整型变量,其值为 3。
p 是一个指向整型的指针,它存储了 a 的地址。
q 是一个指向指针的指针(或称为二级指针),它存储了 p 的地址,即 p 的地址存储在 q 中。

A. q是指针变量,*q就是变量a

这是错误的。q 确实是指针变量,但 *q 是 p,而不是 a。因为 q 指向 p,所以 *q(即 p)是指向 a 的指针,而不是 a 本身。
B. p是指针变量,p指向变量a

这是正确的。p 确实是指针变量,且它指向整型变量 a。
C. q指向变量p,所以*q指向变量a

这是正确的。q 指向 p,而 p 指向 a,所以 *q(即 p)指向 a。
D. *p与**q都代表变量a

这是正确的。*p 是通过 p 指针访问 a 的值,而 **q 首先通过 q 指针访问 p,然后通过 p 指针访问 a 的值,两者都代表 a 的值。
综上所述,错误的选项是 A:q是指针变量,*q就是变量a。

8.有以下不完整函数

int fun(char*p) {
  char *t=p;
  while( *t++);
  return(__); 
}

该函数的功能是:计算p所指字符串占用内存单元的个数作为函数值返回。return语句下划线处应填入的是()。

在这个函数中,char *t = p; 首先将 p 指针的值赋给 t 指针,这样 t 和 p 都指向同一个字符串的开始位置。接着,while( *t++ ); 这个循环会遍历字符串直到遇到字符串的终止符 \0。在这个循环中,*t++ 首先取得 t 指向的字符(在第一次循环中是字符串的第一个字符),然后 t 指针自增,指向字符串的下一个字符。由于循环的条件是 *t++ 的结果(即 t 指向的字符),循环会在 *t 为 \0(即字符串的结束符)时停止,此时 t 指针已经指向了字符串的末尾字符的下一个位置(即 \0 的位置)。

要计算字符串占用的内存单元个数(包括终止符 \0),我们需要知道 t 指针最终停止的位置和 p 指针(即字符串开始的位置)之间的差。

因此,return 语句下划线处应填入的是 t - p

9.

sub函数的作用是将形参y和x的差赋给了z指向的那个内存地址,所以在sub(10,5,&a),10和5属于值传递,直接将数值10和5分别传递给了变量x和y,而对于a是属于地址传递,也就是a与z指向了同一个存储单元,在执行函数后,a的值随*z变化,但b, c值并不改变,所以此次函数被调用后,a的值为y-x=-5,同理可知,在sub(7,a,&b)后,b的值发生变化,其值为-5-7=-12,在sub(a, b,&c)后,c的值发生变化,其值为-12-(-5)=-7。故本题答案为-5,-12,-7。

10.

根据C语言的语法,x++是在使用x之后,再将x的值加1,在if语句中x的值为5,由于条件判断的结果是false,所以执行else分支中的printf ("%d\n",x--);。这里,x--是后缀递减运算符,它会在输出x的当前值(现在为6,因为xif条件判断后递增了)之后,递减x的值。但是,重要的是要注意,递减发生在输出之后,所以输出的是x递减前的值,即6

11.

解析:j=&i,j的值就是i的地址,即j*=100,再将j的地址赋给k,即*k=j,那么**k=*j,而j*=100,所以**k=100,最终打印结果为100.

12.

答案:D

解析:

A. a[p-a]

p-a 计算的是指针 p(指向 a[0])与数组名 a(也视为指向 a[0] 的指针)之间的偏移量,以元素为单位。因为 p 和 a 都指向 a[0],所以 p-a 的结果是 0。因此,a[p-a] 等同于 a[0],这是一个正确的引用。

B. *(&a[i])

&a[i] 获取数组 a 中第 i 个元素的地址。然后,*(&a[i]) 是对这个地址的解引用,即获取 a[i] 的值。这也是一个正确的引用。

C. p[i]

由于 p 被初始化为指向 a[0] 的指针,p[i] 实际上是对数组 a 中第 i 个元素的引用(因为指针算术会将 i 解释为偏移量)。所以,p[i] 等同于 a[i],这是一个正确的引用。

D. *(*(a+i))

在这个表达式中,a+i 计算的是数组 a 中第 i+1 个元素的地址(因为数组索引从0开始)。

*(a+i) 是对这个地址的解引用,即获取 a[i] 的值(一个整数)。但是,外层的 * 试图对这个整数(a[i])再次进行解引用,这在C语言中是不合法的,因为整数不是指针。因此,*(*(a+i)) 是一个错误的引用。

13.

结果:xyabcABC

解析:

strcat(p1,p2)结果是abcABC,strcpy(str+2,strcat(p1,p2))结果是把字符串"abcABC"复制到str+2开始的位置。

字符串复制函数strcpy():

格式:strcpy(字符串1,字符串2)

功能:将字符串2复制到字符串1

注意:参数字符串2可以是字符数组名,也可以是字符串常量。但参数字符串1必须是字符数组名。

字符串1必须有足够的空间,以便能容纳字符串2。

部分复制:strncpy(字符串1,字符串2,n),复制前n个字符。

字符串连接函数strcat():

格式:strcat(字符串1,字符串2)

功能:连接两个字符串

注意:参数字符串2可以是字符数组名,也可以是字符串常量。但参数字符串1必须是字符数组名。

字符串1必须有足够的空间,以便能容纳字符串2。

14.

解析:

这个二维数组被初始化为只有对角线元素被明确赋值(2, 4, 6),其他元素默认初始化为0。因此,数组aa的内容是:

2  0  0  
0  4  0  
0  0  6

这里定义了一个整型变量i和一个指向整型的指针p,并将p初始化为指向aa[0][0]的地址。

  • i=0时,执行if语句块:aa[0][1] = *p + 1,即aa[0][1] = 2 + 1 = 3。此时p仍然指向aa[0][0]
  • 然后打印*p的值,即aa[0][0]的值,输出2
  • i=1时,不执行if语句块,直接执行++p,使得p指向aa[0][1]
  • 然后打印*p的值,即aa[0][1]的值,输出3。

最终程序的输出结果是:23

15.

解析:

当switch后面括孤内的表达式的值与某一个case后面的常量的表达式的值相等时,就执行此case后面的语句(因为case后面的语句没有break,所以后面的语句都会执行一遍),若所有的ease中的常量表达式的值都没有与表达式的值匹配的,就执行default后面的语句。

所以输出结果是:v1=5,v2=8,v3=6,v4=1

16.

答案:C

解析:

w = k; // 将w初始化为k的值  
LB: // 标签LB,用于goto语句跳转  
if (w == 0) goto LE; // 如果w等于0,跳转到LE标签处  
w--; // 将w减1  
printf("*"); // 打印一个*  
goto LB; // 跳转到标签LB处,形成循环  
LE: // 标签LE,表示循环结束

这个程序段的逻辑是:

  1. 首先,将变量w初始化为k的值。
  2. 然后,检查w是否等于0。如果是,就跳转到标签LE处,跳出循环。
  3. 如果w不等于0,就执行w--w的值减1,并打印一个*字符。
  4. 使用goto语句跳转到标签LB处,再次检查w的值,如果仍然不等于0,则重复上述步骤(减1并打印*),直到w变为0为止。
  5. w变为0时,跳过w--printf("*")语句,直接执行到标签LE:处,表示循环结束。

这个循环的目的是打印出k*字符,其中kw的初始值。例如,如果k是5,那么程序将打印*****

现在,我们来看一下每个选项与这个goto程序段的等价性:

A. for(w=k; w!=0; w--) printf("*");

  • 这个for循环与goto程序段完全等价。它首先初始化wk,然后在w不等于0的条件下循环,每次循环都将w减1并打印一个*

B. w=k; while(w--!=0) printf("*"); w++;

  • 这个循环在逻辑上与goto程序段相似,由于w--在比较之前先对w进行了减1操作,因此它实际上会在w从1变为0时停止循环(因为w--在比较中的值是减1之前的值)。

C. w=k; do { w--; printf("*"); } while(w != 0);

  • 这个选项中的do-while循环首先无条件地执行一次循环体,其中w被减1,并打印一个*。然后,它检查w是否不等于0。如果w仍然不等于0(即它还没有被减到0),循环就会继续。这个过程会一直重复,直到w变为0,此时循环条件变为假,循环结束。
  • 但考虑k=0的情况,此选项会无限循环"*",其他选项不会输出"*",因此不符合题目要求。

D. for(w=k; w; --w) printf("*");

  • 这个for循环也与goto程序段等价。它利用了for循环的隐式条件检查(w作为条件,当w为0时视为假),并在每次循环结束时将w减1。只要w不为0,就会执行循环体打印*

17、有以下程序

#include <stdio.h>

main(){
int a=7, b=0;

do{
 b+= a;
 a-=1 ;
}while (a--);
printf("%d,%D\n", b, a);
}
执行后的输出结果是

A.16,-1

B.28,1

C.16,0

D.28,0

解析:

第一次循环:b=b+a=0+7=7 ,a=a-1=7-1=6,此时a--,a=5

第二次循环:b=b+a=7+5=12 ,a=a-1=5-1=4,此时a--,a=3

第三次循环:b=b+a=12+3=15 ,a=a-1=3-1=2,此时a--,a=1

第四次循环:b=b+a=15+1=16 ,a=a-1=1-1=0,此时a--(条件为假,退出循环),a=-1

所以输出结果为16,-1,答案选A。

18、有以下程序

#include <stdio.h>

main(){
  int x, y=0,z=0,t ;
do
{
   scanf(" %d",&x);

t=x>0;
switch (t)
{
  case 0 : break;
  case 1:y+=x; continue;
}
  z+=x;
}while(x);
  printf ("%d,%d\n" ,y,z);

}

程序运行时输入:-1 1 -2 2 0<回车>,则输出结果是_
A.1,1             B.1,0            C.3,-3              D.3,0

解析:

第一步输入-1,x=-1, x>0不成立,t=0,跳出switch语句,z=z+x=-1;

第二步输入1,x=1,x>0成立,t=1,y=y+x=1,跳出本次循环,直接执行下一次循环;

第三步输入-2,x=-2,x>0不成立,t=0,跳出switch语句,z=z+x=-3;

第四步输入2,x=2,x>0成立, t=1,y=y+x=3,跳出本次循环,直接执行下一次循环;

第五步输入0,x=0, x>0不成立,t=0,跳出switch语句,z=-z+x=-3,结束do-while循环。

最后输出y=3,z=-3,故选项C正确。
 

19、有以下程序

#include <stdio.h>

main(){
  int x, a=1, b=1 ;

while(1){
scanf("%d",&x);
if(x>0) { a*=x ; break; }

if(x<0)( b*=x ; continue; }

printf("%d,%d\n",a, b);
 }
}
程序运行时输入:-1 -2 0 1 2<回车>,则输出结果是

A.1,2         B.2,2          C.-1,1         D.-2,1

解析:

第一步x=-1,x<0成立,b=b*x=-1,a=1,执行continue语句,结束本次循环。

第二步x=-2,x<0成立,b=b*x=2,a=1,执行continue语句,结束本次循环。

第三步x=0,直接执行输出语句,输出1,2。

第四步x=1, x>0成立,b=b*×=2,a=1,执行break语句,直接跳出循环。

故本题答案选A。

20、有以下程序

#include <stdio.h>

main(){
  int i, j;
  for( i=3; i>0; i--){
     for(j=1; j<=i; j++)
         putchar ( '*');

         for(j=1;j<=3-i; j++)

         putchar('#');
         putchar('\n');
   }
}
执行后输出结果是

A.*** **# *##
B.**# *## ###
C.### ##* #**
D.##* #** ***

解析:

第一步 i=3:第二个for循环j=1, j<=i成立,输出*;  j=2,j<=i成立,输出*, j=3, j<=i成立,输出*;第三个for循环中,j=1,j<=3-i=0不成立,直接输出换行符。此时结果为***

第二步 i=2:第二个for循环j=1,j<=i成立,输出*, j=2,j<=i成立,输出*,j=3,j<=i不成立,循环结束;第三个for循环中,j=1,j<=3-i=1成立,输出#;j=2,j<=3-i=1不成立,直接输出换行符。此时结果为*** **#

第三步 i=1:第二个for循环j=1, j<=i成立,输出*,j=2,j<=i不成立,循环结束;第三个for循环中,j=1,j<=3-i=2成立,输出#,j=2,j<=3-i=2成立,输出#,j=3,j<=3-i=2不成立,直接输出换行符。此时结果为*** **# *##

故选项A正确。所以本题答案选A。

21、有以下程序

#include <stdio.h>  
  
int *f(int *s) {  
    s[1] += 6;  
    *s = 7;  
    s += 2;  // 指针 s 向前移动两个整数的位置  
    return s;  
}  
  
int main() {  
    int a[5] = {1, 2, 3, 4, 5}, *p = a;  
    p = f(p);  
    printf("%d,%d,%d\n", a[0], a[1], *p);  
    return 0;  
}

程序运行后输出的结果是

A.7,8,3

B.7,8,7

C.9,8,9

D.1,2,1

解析:

1.数组 a 被初始化为 {1, 2, 3, 4, 5}

2.指针 p 初始化为指向数组 a 的第一个元素(即 a[0])。

3.函数 f 被调用,传入指针 p(此时 p 指向 a[0])。

        1.在函数内部,s[1] 被修改为 2 + 6 = 8(因为 s 指向 a[0],所以 s[1] 是 a[1])。

        2.*s 被设置为 7,即 a[0] 被修改为 7

        3.指针 s 向前移动两个整数的位置,现在它指向 a[2]

        4.函数返回修改后的指针 s,即指向 a[2] 的指针。

4.在 main 函数中,p 被更新为 f 函数返回的指针,即现在 p 指向 a[2]

5.打印 a[0]a[1] 和 *p 的值。a[0] 是 7(因为 *s = 7;)。a[1] 是 8(因为 s[1] += 6;)。*p 是 a[2] 的值,即 3(因为虽然 p 指向 a[2],但 a[2] 的值在 f 函数中未被 修 改)。

因此,程序运行后输出的结果是:7,8,3

22、有以下程序

#include <stdio.h>     
 void fun(int a[], int n, int flag) {  
    int i = 0, j, t;  
    for (i = 0; i < n - 1; i++)  
        for (j = i + 1; j < n; j++)  
            if (flag) {  
                if (a[i] < a[j]) {  
                    t = a[i];  
                    a[i] = a[j];  
                    a[j] = t;  
                }  
            } else {  
                if (a[i] > a[j]) {  
                    t = a[i];  
                    a[i] = a[j];  
                    a[j] = t; 
                }  
            }  
}
main(){
int c[10]={7,9,10,8,3,5,1,6,2,4}, i ;
fun( c,4,1 );
fun( c+4,6,0);
for ( i=0;i<10; i++ )
printf("%d,",c[i] );
printf("\n");
}

程序运行后输出的结果是:

A.10,9,8,7,1,2,3,4,5,6

B.10,9,8,7,6,5,4,3,2,1

C.7,8,9,10,6,5,4,3,2,1

D.1,2,3,4,5,6,7,8,9,10

解析:

程序中的 fun 函数用于根据 flag 参数对数组进行排序。如果 flag 为 1,则进行降序排序;如果 flag 为 0,则进行升序排序。

首先,程序对数组 c 的前 4 个元素进行降序排序(fun(c, 4, 1);),然后对其余的 6 个元素(从 c+4 开始)进行升序排序(fun(c+4, 6, 0);)。

  1. 降序排序部分 (fun(c, 4, 1);):
    • 原始数组: 7, 9, 10, 8, 3, 5, 1, 6, 2, 4
    • 降序排序后(前 4 个元素): 10, 9, 8, 7, 3, 5, 1, 6, 2, 4
  2. 升序排序部分 (fun(c+4, 6, 0);):
    • 排序前的后半部分: 3, 5, 1, 6, 2, 4
    • 升序排序后(后 6 个元素): 1, 2, 3, 4, 5, 6

因此,程序运行后的输出结果是:10,9,8,7,1,2,3,4,5,6

23、有以下程序

#include <stdio.h>  
  
void f1(char *a, char b) {  
    char c;  
    c = *a;  
    *a = b;    
    b = c;  // 注意:这里不能修改b的值,因为b是按值传递的
}  
  
void f2(char a, char b) {  
    char c;  
    c = a;  
    // 注意:这里不能修改a和b的值,因为它们是按值传递的  
    b = c; // 只在函数内部有效  
}  
  
void f3(char *a, char *b) {  
    char c;  
    c = *a;  
    *a = *b;  
    *b = c;  
}  
  
int main() {  
    char t1, t2;  
    t1 = 'A';  
    t2 = 'B';  
    f3(&t1, &t2);  
    putchar(t1);  
    putchar(t2);  
    t1 = 'A';  
    t2 = 'B';  
    f2(t1, t2);  
    putchar(t1);  
    putchar(t2);  
    t1 = 'A';  
    t2 = 'B';  
    f1(&t1, t2);  
    putchar(t1);  
    putchar(t2);  
    printf("\n");  
    return 0;  
}

程序运行后输出的结果是:

A.BAABBB

B.ABBABB

C.BABABA

D.BABAAB

解析:

f3 函数:这个函数交换了两个字符变量 t1 和 t2 的值。通过指针,函数内部修改了这两个变量的值。因此,t1 变为 'B't2 变为 'A'。输出为 BA

f2 函数:这个函数尝试交换两个字符变量 a 和 b 的值,但由于它们是按值传递的,函数内部的修改不会影响到原始的变量。因此,t1 和 t2 的值在调用 f2 后不变。输出为 AB

f1 函数:这个函数接收一个字符指针 a 和一个字符 b,然后交换了 *a(即指针指向的字符)和 b 的值。注意,b 是按值传递的,所以原始的 t2 不会被修改,但 t1 的值会被修改为 b 的值(即 'B')。输出为 BB

因此,程序运行后的输出结果是:BAABBB。选择答案A。

24、若有语句: int a[3][4],(*p)[4],p = a,则以下选项中叙述错误的是:

A.系统将开辟一个名为p的二维数组,p[0][0]中的值即为a[0][0]中的值

B.p+1代表a[1][0]的地址

C.p中将存放a数组的首地址

D.p+2代表a数组最后一行的首地址

解析:

int a[3][4]; 定义了一个3行4列的二维数组 a。

int (*p)[4]; 定义了一个指针 p,这个指针指向一个包含4个整数的数组(即指向一个4元素的整数数组)。

p = a; 将 a 的地址(实际上是 a 数组第一行的地址)赋给 p

现在,我们逐一分析每个选项:

A. 系统将开辟一个名为p的二维数组,p[0][0]中的值即为a[0][0]中的值

  • 错误。p 是一个指针,不是二维数组。它指向一个包含4个整数的数组,而不是直接存储这些整数。p[0] 实际上是指向 a[0](即 a 的第一行)的指针,而 p[0][0] 则等价于 a[0][0],但这里的逻辑解释(系统开辟一个名为p的二维数组)是不正确的。

B. p+1代表a[1][0]的地址

  • 正确。在对指针进行加减运算时,数字"1是指一个存储单元长度。增1表示指向地址值大(高地址)的方向移动一个存储单元,减1表示向地址值小(低地址)的方向移动一个存储单元。
    p 指向 a[0],因此 p+1 指向 a 的下一行,即 a[1],而 a[1] 的地址可以视为 a[1][0] 的地址(在二维数组的上下文中)。

C. p中将存放a数组的首地址

  • 正确(但表述略有模糊)。更准确地说,p 中将存放 a 数组第一行(即 a[0])的地址。由于二维数组在内存中是连续存储的,且每行大小相同,所以 a 数组的首地址和 a[0] 的地址在数值上是相同的。

D. p+2代表a数组最后一行的首地址

  • 正确。由于 p 指向 a[0]p+1 指向 a[1],那么 p+2 自然指向 a 的第三行(即最后一行),也就是 a[2] 的首地址。

综上所述,错误的选项是 A

25、有以下程序

#include <stdio.h>
int new_div(double a,double b){
return a/b+0.5;
}
main(){
 printf(" %d" , new_div(7.8,3.1));
}

程序运行后的输出结果是:
A.0     B.1      C.2         D.3

解析:

new div函数被定义为int类型,所以返回值a/b、+0.5也是int类型。a/b+0.5=8/3+0.5=2+0.5=2.5,转换为整型后,四舍五入经计算得出,返回值为3,故D选项正确。所以本题答案为D。

26、有以下程序

#include <stdio.h>
void change( char* array,int len ){
for(len--; len>=0; len--)
array[len] += 1 ;
}
main()
{
int i;
char array [5]="ABCD";change (array,4);
for(i=0; i<4; i++)
printf("%c," , array[i]);
}

程序运行后的输出结果是:

A.  B,C,D,E

B.  A,B,C,D

C.  C,D,E,F

D.  B,D,F,H

解析:

  1. 循环开始len是4,进入循环体。
    • len--len变为3。
    • array[len]array[3]'D'(ASCII 68)。
    • array[len] += 1'D'(ASCII 68)变为'E'(ASCII 69)。
  2. 循环继续len是3,继续循环。
    • array[len]array[2]'C'(ASCII 67)。
    • array[len] += 1'C'(ASCII 67)变为'D'(ASCII 68)。
  3. 循环继续len是2,继续循环。
    • array[len]array[1]'B'(ASCII 66)。
    • array[len] += 1'B'(ASCII 66)变为'C'(ASCII 67)。
  4. 循环继续len是1,继续循环。
    • array[len]array[0]'A'(ASCII 65)。
    • array[len] += 1'A'(ASCII 65)变为'B'(ASCII 66)。
  5. 循环结束len是0,但循环条件是len >= 0,所以这一轮不执行循环体。循环结束。

for(len--; len>=0; len--)这个循环中,有两个len--表达式,但它们的作用和时机是不同的,因此它们是“互不干扰”的。

最后程序输出的结果是:B,C,D,E。选择答案A。

27、设有定义: int x[10],*p=x, i若要为数组x读入数据,以下选项正确的是:

A.
 for(i=0; i<10; i++)
 scanf(" %d" , p+i);

B.
 for (i=0;i<10; i++)
 scanf("%d",*p+i);       

C.
 for(i=0;i<10; i++)
 scanf(" %d",*(p+i));

D. 
 for(i=0; i<10; i++)
 scanf("%d",x[i]);

解析:

1.int x[10] 定义了一个整型数组 x,它有 10 个元素。

2.*p = x 定义了一个整型指针 p,并将其初始化为指向数组 x 的第一个元素。

3.使用 p+i 可以访问数组 x 的第 i+1 个元素(因为 p 指向 x[0],所以 p+1 指向 x[1],依此类推)。

4.使用 *(p+i) 或 p[i](这两者等价)可以获取数组 x 的第 i 个元素的值。

现在,我们逐一分析选项:

A. for(i=0; i<10; i++) scanf(" %d" , p+i);
        这个选项是正确的。p+i 是一个指向 x[i] 的指针,scanf 需要一个指向变量的指针来存储输入的数据,这里 p+i 正好满足这个要求。

B. for (i=0;i<10; i++) scanf("%d",*p+i);
        这个选项是错误的。*p 是 x[0] 的值,一个整数,而不是一个指针。因此,*p+i 试图将一个整数和一个整数相加,结果仍然是一个整数,而不是一个地址。scanf 需要一个地址来存储输入的数据,所以这里会导致未定义行为。

C. for(i=0;i<10; i++) scanf(" %d",*(p+i));
        这个选项也是错误的。虽然 *(p+i) 可以获取 x[i] 的值,但 scanf 需要一个指向变量的指针,而不是变量的值。因此,这里传递了一个整数(x[i] 的值)给 scanf,而不是一个地址。

D. for(i=0; i<10; i++) scanf("%d",x[i]);
        这个选项同样是错误的。x[i] 是数组 x 的第 i 个元素的值,不是一个地址。scanf 需要一个地址来存储输入的数据,所以这里同样会导致未定义行为。

综上所述,只有选项 A 是正确的。

28、若在定义语句: int a,b,c, *p=&c;之后,接着执行以下选项中的语句,则能正确执行的语句是____。
A.scanf("%d",a,b,c);
B.scanf(”%d%d%d”,a,b, c);

C.scanf("%d”,p);
D.scanf("%d" ,&p);

解析:

A. scanf("%d",a,b,c);
这个语句是错误的,因为scanf的第二个参数应该是一个地址,而这里abc都是变量名,不是地址。正确的形式应该是使用&操作符来获取变量的地址,例如&a&b&c

B. scanf("%d%d%d",a,b, c);
这个语句同样是错误的,原因与A选项相同,abc都应该被替换为它们的地址&a&b&c

C. scanf("%d",p);
这个语句是正确的。因为p是一个指向c的指针,所以p存储的是c的地址。scanf函数可以通过指针p来向c中写入数据。

D. scanf("%d", &p);
这个语句是错误的,因为&p取得的是指针p的地址,而不是一个整数变量的地址。p本身是一个指针变量,存储了c的地址,但&p存储的是p这个指针变量自身的地址,这与我们想要通过scanf读取一个整数到c中的目标不符。

因此,答案选择C。

29、有以下函数

int aaa (char *s)

{  char *t=s;

while(*t++);

t--;

return(t-s);

}

以下关于aaa函数的功能叙述正确的是_

A.求字符串s的长度

B.比较两个串的大小

C.将串s复制到串t

D.求字符串s所占字节数

解析:

char *t = s; // 创建一个指针t,并将其初始化为指向s所指向的地址  
while(*t++); // 这个循环会一直执行,直到遇到字符串s的末尾('\0'字符)。每次循环,指针t都会向前移动一位。  
t--; // 循环结束后,t指向了字符串s的末尾字符'\0'的下一个位置。这里将t回退到'\0'的位置。  
return(t-s); // t - s计算的是从s到t(即'\0'字符的位置)之间有多少个字符,也就是字符串s的长度(不包括末尾的'\0'字符)。

答案选择A。

30、若有定义语句: int a[2][3],*p[3];则以下语句正确的是___。

A.p=a;

B.p[0]=a;

C.p[0]=&a[1][2];

D.p[1]=&a;

解析:

int a[2][3];:这是一个二维数组,有2行3列,总共6个整数元素。

int *p[3];:这是一个指针数组,包含3个指向整数的指针。

A. p=a;
这个选项是错误的。因为p是一个指针数组(即一个包含指针的数组),而a是一个二维数组(或数组的数组)。在C语言中,二维数组名(如a)可以被视为指向其第一行(即一个包含3个整数的数组)的指针,但这不是一个普通的整数指针,而是一个指向数组的指针,即int (*)[3]类型,与int *[](即p的类型)不兼容。

B. p[0]=a;
这个选项同样是错误的,但原因与A选项略有不同。p[0]是一个指向整数的指针(int *),而a(或更准确地说是&a[0])是一个指向包含3个整数的数组的指针(int (*)[3])。因此,类型不匹配,赋值不合法。

C. p[0]=&a[1][2];
这个选项是正确的。&a[1][2]是取地址操作,它获取的是a数组中第二行第三个元素的地址(即a[1][2]的地址)。这个地址是一个指向整数的指针,与p[0]的类型(int *)相匹配。

D. p[1]=&a;
这个选项是错误的。&a是二维数组a的地址,其类型是指向包含2个int[3]数组的指针(即int (*)[2][3]),这与p[1](一个int *类型的指针)不兼容。

综上所述,正确答案是C。

31、有以下程序

#include <stdio.h>  
  
void fun(char *t, char *s) {  
    while (*t != 0) t++; // 移动到t的末尾  
    while (*t++ = *s++) != 0); // 从s复制字符到t的末尾,直到遇到s的末尾字符'\0'  
}  
  
int main() {  
    char ss[10] = "acc ";  
    char aa[10] = "bbxxyy";  
    fun(ss, aa);  
    printf("%s,%s\n", ss, aa);  
    return 0;  
}

程序的运行结果是()
A.accxyy, bbxxyy

B.acc, bbxxyy

C.accxxyy,bbxxyy

D.accbbxxyy,bbxxyy

解析:

    本题fun函数中第一个while循环是找到字符串t的结束字符,第二个while循环的功能是将宁符串s中的各字符依次存入到字符串t的尾部,由于数组ss与指针变量t指向同一存储单元,所以输出的ss的字符串为" accbbxyy”,字符串aa的内容不变,即"bbxyy"。故本题答案为D

32、已有定义: char str[5][10]={"Monday","Tuesday", "Wednesday" "Thursday" "Friday"},可以正确输出day的语句是
A. puts(*str+15);
B. puts(*(str+1));

C. puts(*str+3);

D. puts((*(str+4)+2));

解析:根据题意,定义了5行10列的二维数组str并存放了五个字符串,其中数组名str代表数组首素地址相当于个行指针,*str等价于str[0]代表二维数组第一行的地址。
因为数组str每一行都有10个元素,所以*str+15代表第二行第六个元素'a'的地址值,puts(*str+15)输出字符串"ay"。str相当于行指针,str+1代表第二行首地址,所以puts(*str+1)输出字符串"Tuesday"; *str+3代表第一行第四个元索'd'的地址值,所以puts(*str+3)输出字符串"day"; *(str+4)+2)代表第五行第三个元素"i"的地址值,所以输出字符串"iday"。因此,本题答案为C。
 

33、若有定义:int w[3][5];,则以下不能正确表示该数组元素的表达方式是_
A.*(*w+3)
B.*(w+1)[4]

C.*(*(w+1))

D.*(&w[0][0]+1)

解析:本题考查的是数组的表达方式。

选项A:*(*w +3)=*(*(w+0)+3)=*(w[0]+3)=w[0][3],符合数组定义的范围可以正确表示数据元素。

选项B:*( w+1)[4]=*(*(w+1)+4)=*w[5]=w[5][0],超出了数据定义的范围。

选项C:*(*(w+1))=*w[1]=w[1][0],符合数组定义的范围可以正确表示数据元素。

选项D:*(&w[0][0]+1)=*(w[0]+1)=w[0][1],符合数组定义的范围可以正确表示数据元素。

故本题答案为B。

34、以下语句或语句组中,能正确进行字符串赋值的是__。
A.char *sp;*sp="right!";
B.char s[10];s="right!";

C.char s[10];*s= "right!";

D.char *sp="rig ht!";

【正确答案】D
【题目解析】
本题考查的是字符串的赋值。

选项A定义了一个字符型的指针变量sp,则*sp存储的是第一个字符,而选项A中给它赋的是字符串,所以错误,如果将*sp="right"改成sp= "right"就对了,即把字符审"right'的首地址赋始给了指针变量sp;

选项B定义了一个字符型的数组s[10],则s表示代表数组的首地址,而题中给它赋的是字符串,所以错误,要对字符数组赋值,只能在定义数组时,对其进行初始化.

选项C定义了一个字符型的数组s[10],再通过*s给数组元素赋初值,在此,由于*s指的是数组的第一个元素,而题中给它赋的是字符串,所以错误。

故本题答案为D。

35、若有定义:char *x="abcdefghi”;,以下选项中正确运用了strcpy函数的是___。
A.char y[10]; strcpy(y,x[4]);
B.char y[10]; strcpy(++y,&x[1]);

C. char y[10],*s; strcpy(s=y+5,x);

D.char y[10],*s;strcpy(s=y+1,x+1);

【正确答案】D
【题目解析】
本题考查的是用于字符串处理的函数。

选项A中x[4]是取字符e,也就是将宁符复制到y中,strcpy实现的是地址的复制.所以选项A错误.

选项B中++y是错误的,不允许对常量进行自加运算(是一个确定的地址值)所以选项B错.

选项C指针变量s指向了y向后的第5位,则存放时会出现越界问题,所以选项C错。

选项D中,指针变量s指向了y向后的第一位,此时s可存放数据的长度为9,而地址×+1起的字符串的地址长度也刚好为9(包括“\0”),所以开始复制不会出现地址越界问题。

故本题答案为D。

36、

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值