第一题
1. 对于函数void f(int x);,下面调用正确的是()
A:int y = f(9);
B:f(9);
C:f( f(9) );
D:x=f();
答案及解析 B
函数调用要看返回值和传参是否正确;
A:错误,该函数没有返回值;
B:正确;
C:错误,f(9) 没有返回值,所以不能作为f函数的参数;
D:错误,f函数既不能赋值给变量,并且需要传参;
第二题
2.假设编译器规定int 和 short 类型长度分别为 32 位和 16 位,得到y 的机器数为( )。
unsigned short x = 65530;
unsigned int y = x;
A:0x0000 7FFA
B:0x0000 FFFA
C:0xFFFF 7FFA
D:0xFFFF FFFA
答案及解析 B
本题考查的是隐式类型转换,这两个变量x,y都是无符号类型,但是x是short类型,给y赋值的时候,会拷贝一个临时变量,将这个临时变量隐式类型转换到y的类型,再赋值给y,因为是低位到高位,转换的时候是整型提升,都是无符号数,高位补0,结果不变;
图解:
第三题
3. 如果x=254,函数返回值为:
int func(int x)
{
int countx = 0;
while(x)
{
countx ++;
x = x & (x - 1);
}
return countx;
}
A:6
B:7
C:8
D:0
答案及解析 B
本题考查的是位运算:常见位运算的公式大全(建议收藏,以防走丢)-CSDN博客
x & (x - 1)是消去二进制数最右边的1,所以countx计算的是一共有多少个1;
x = 254
二进制: 0000 1111 1110 一共有7个1,所以结果为7
第四题
4. 下列程序,若输入字符串abc,则函数f的功能是将字符串abc转换为*abc输出,请为横线处选择合适的程序( )
void f(char str[5])
{
int i = strlen(str) - 1;
while (i >= 0)
{
str[i + 1] = str[i];
i--;
}
_________________;
printf("%s\n", str);
}
A:str[ i + 1 ] = ' * '
B:str[ i ] = ' * '
C:str[ 1 ] = ' * '
D:str[ i - 1 ] = ' * '
答案及解析 A
要实现功能abc 变成 *abc,也就是要挪动数据,一个一个覆盖,循环的功能就是将字符串往后整体移动,然后横线上就是把第一个位置的元素变成 *
第一种:str[ 0 ] = ' * ';
第二种,可以借助 i ,此时 i 已经为 -1,所以也可以这样:str [ i + 1 ] = ' * '
第五题
5.若有定义:int a[4][10],则下列选项中对数组元素a[ i ] [ j]引用错误的是()
A:*(a + i) + j
B:*(&a[ 0 ][ 0 ] + 10 * i + j)
C:*(a[ i ] + j)
D:*(*(a + i) + j)
答案及解析 A
对数组元素的引用,这里为了方便图解,设置 i 值为1,j 值为2;
A:a是二维数组名,是数组首元素的地址,而二维数组的首元素是整个的一维数组,所以
二维数组的数组名是一维数组的地址,相当于a = &a[0],a + i 就相当于 &a[0] + 1 = &a[1]就是往后移动1个数组的地址,解引用*(a + 1) = *&a[1] = a[1],所以解引用之后是拿到一维数组元素的地址,a[1] + 2 = a[3] ,是数组第四个元素的地址,并不是数组元素;
B:正确,先拿到数组元素的地址,之后进行指针+整数,再解引用一定是数组元素;
C:二维数组的行代表的是该行首元素的地址,外层一次解引用,得到的就是数组元素;
D:这里是两次解引用,*(*(a + i) + j) = *(a[ i ] + j) = a[ i ][ j ];