假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include
int main(){
long long a = 1, b = 2, c = 3;
printf("%d %d %d\n", a, b, c);
return 0;
}
A 1,2,3
B 1,0,2
C 1,3,2
D 3,2,1
正确答案:B
这题的考点就是大小端字节序与函数传参顺序
关于大小端问题就是数据在内存中的存储顺序
大端模式(大端字节序):数据的低字节
保存在内存的高地址
中,高字节
保存在低地址
中
小端模式(小端字节序):低位
存低地址
,高位
存高地址
下图这就是标准的小端存储
还有一个就是函数传参顺序,调用printf函数需要压栈建立函数栈帧,函数传参是从右向左的,下面就可以看到,不管a,b,c是谁先定义,都只与传参顺序有关。栈底是高地址,栈顶是低地址
a,b,c都是long long类型8字节,而%d只会获取4字节
如下代码输出的是
char a=101;
int sum=200;
a+=27;sum+=a;
printf("%d\n",sum);
A: 327
B: 99
C: 328
D: 72
以下程序的输出结果是
#include
int main()
{
int x = 3, y = 3;
switch (x % 2) {
case 1:
switch (y) {
case 0:cout << "first";
case 1:cout << "second"; break;
default: cout << "hello";
}
case 2:cout << "third";
}
}
A second third
B hello
C first second
D hellothird
正确答案:D
这题的考点就是switch case语句的理解,当进入case语句没有break时,就会继续按顺序执行,还有break与continue,continue只会跳出当前循环,然后判断是否满足下一次的循环条件
#include
int main()
{
int a = 1, b = 2, c = 3, d = 0;
if (a == 1 && b++ == 2)
if (b != 2 || c-- != 3)
printf("%d,%d,%d\n", a, b, c);
else
printf("%d,%d,%d\n", a, b, c);
else
printf("%d,%d,%d\n", a, b, c);
return 0;
}
下面程序输出的是
A 1, 2, 3
B 1, 3, 2
C 3, 2, 1
D 1, 3, 3
正确答案:D
这题的考点就是逻辑语句的短路原则
if(表达式一 || 表达式二)当表达式一为真时,就不会执行表达式二
if(表达式一 &&表达式二) 当表达式一为假 时,就不会执行表达式二
所以b != 2位真后就不会执行后面的
比如我们有时要拿栈顶的元素与val比较时,只有栈不为空时才能取栈底元素
if (!st.empty() && st.top() == val)
#include
using namespace std;
int main()
{
int m = 0123, n = 123;
printf("%o %o\n", m, n);
return 0;
}
程序运行后的输出结果是()
A 0123 0173
B 0123 173
C 123 173
D 173 173
正确答案:C
这题就是C语言常见进制的表示形式以及打印格式化数据的方式
二进制: 101b
八进制:0123 printf打印时 %o
十进制: 101 printf打印时 %d
十六进制:0x123 printf打印时 %x
m是八进制,所以直接打印123
以下程序的运行结果是()
int main()
{
printf("%s , %5.3s\n", "computer", "computer");
return 0;
}
A computer, puter
B computer, com
C computer, computer
D computer, compu.ter
正确答案:B
这题考点与上面类似,也是打印格式化的数据
%m.ns,m表示宽度,n表示打印字符的个数,右对齐,不足补空格,当n大于m时直接打印n个字符。-m就是左对齐,还有%04d右对齐打印,宽度为4,不足补0
求函数返回值,输入x = 9999
int func(int x) {
int count = 0;
while (x)
{
count++;
x = x & (x - 1);
}
return count;
}
A:8
B:9
C:10
D:12
正确答案:A
这题的考点就是计算一个数中1的个数,x=x&(x-1)会不断将x中的1变为0,到最后所有位都为0时循环也就结束了,9999转化为2进制有8个
同样的还有计算一个数中0的个数
while (x + 1)
{
x = x | (x + 1);//计算0的个数
++count;
}
#include
int cnt = 0;
int fib(int n)
{
cnt++;
if (n == 0)
return 1;
else if (n == 1)
return 2;
else
return fib(n - 1) + fib(n - 2);
}
int main()
{
fib(8);
printf("%d", cnt);
}
下列程序执行后, 输出的结果为()
A 41
B 67
C 109
D 177
正确答案:B
这题的考点就是计算函数调用的次数,实际上就是计算斐波那契的次数,因为fib(8)最后递推到fib(0)和fib(1),利用递归的思想,我们可以直接回归到f(0)开始计算
fib(0) 1
fib(1) 1
fib(2) 1+fib(1)+fib(0) = 3
fib(3) 1+fib(2)+fib(1) = 5
fib(4) 1+fib(3)+fib(2) = 9
fib(5) 1+fib(4)+fib(3) = 15
fib(6) 1+fiib(5)+fib(4) = 25
fib(7) 1+fib(6)+fib(5) = 41
fib(8) 1+fib(7)+fib(6) = 67
请声明一个指针,其所指向的内存地址不能改变,但内存中的值可以被改变。
A const int const *x = &y;
B int * const x = &y;
C const int *x = &y;
D int const *x = &y;
E const int * const x = &y;
正确答案:B
这题的考点就是常量指针与指针常量的认识。
指针常量
:指针本身是一个常量,指针的指向不能改变,但指针所指向的值可以发生改变,可以通过解引用改变指针所指向空间的值
常量指针
:指向常量的指针,不能通过解引用改变指针所指向的空间的值,但指针的指向可以发生改变
区分:const与*的相对位置
const在*左边修饰的是指针所指的空间,所以是常量指针,const在*右边修饰的是指针,所以是指针常量
下面叙述错误的是()
char acX = "abc";
char acY[] = { 'a','b','c' };
char* szX = "abc";
char* szY = "abc";
A acX与acY的内容可以修改
B szX与szY指向同一个地址
C acX占用的内存空间比acY占用的大
D szX的内容修改后,szY的内容也会被更改
正确答案: D
这题考点和上面类似,判断的是字符数组与字符指针的区别,字符数组是从常量区将字符串拷贝到数组,数组中存放的字符串是可以修改的,而字符指针是指向在常量区的常量字符串,不可修改,szX与szY指向的都是那个常量字符串,所以指向的是同一个地址
C选项,因为acY里面没有\0,而acX会带\0,所以正确
下面程序打印的结果是
#include
int main()
{
char p1[15] = "abcd", *p2 = "ABCD", str[50] = "xyz";
strcpy(str + 2, strcat(p1 + 2, p2 + 1));
printf("%s", str);
}
A xyabcAB
B abcABz
C ABabcz
D xycdBCD
E 运行出错
正确答案:D
这题的考点就是对字符函数stcpy和strcat的认识,拷贝和追加的目的地空间都要足够大,不然程序就会崩溃运行出错。strcat会返回追加后的目的地址,也就是p1+2
假设函数原型和变量说明如下,则调用合法的是( )
void f(int **p);
int a[4]={1,2,3,4};
int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *q[3]={b[0],b[1],b[2]};
A: f(a);
B: f(b);
C: f(q);
D: f(&a);
正确答案:C
这题的考点就是对指针和数组的掌握
A选项:数组名是首元素地址,应该用int* p接收
B选项:数组名是首元素地址,也就是一维数组的地址,应该用int(*p)[ ]接收
C选项:q是一个指针数组,数组ing是首元素地址,也就是b[o]的地址,b[o]是一个一维数组,但数组传参会退化成指针,所以是一个一级指针的地址,可以用int** p接收
D选项:&数组名,应该用int(*p)[ ]接收
#include
int main()
{
int n[][3] = { 10,20,30,40,50,60 };
int(*p)[3];
p = n;
cout << p[0][0] << "," << *(p[0] + 1) << "," << (*p)[2] << endl;
}
下面程序的输出结果是
A 10, 30, 50
B 10, 20, 30
C 20, 40, 60
D 10, 30, 60
正确答案:B
这题的考点同样是对数组与指针的掌握情况n是一个2行3列的二维数组,p是一个数组指针,指向的是一个有3个元素的int型数组
数组 a 的定义为: int a[3][4]; 下面哪个不能表示 a[1][1] ( )
A: *(&a[0][0]+5)
B: *(*(a+1)+1)
C: *(&a[1]+1)
D: *(a[1]+1)
正确答案:C
C选项实际表示的是a[2][0]
void (*s[5])(int) 表示意思为( )
A: 函数指针 B: 函数指针数组 C: 数组指针函数 D: 语法错误
正确答案:B
s先和[ ]结合,所以是一个数组有5个元素,元素类型是void(*)(int)函数指针,所以s是一个函数指针数组
下面两个结构体
struct One
{
double d;
char c;
int i;
};
struct Two
{
char c;
double d;
int i;
};
在#pragma pack(4)和#pragma pack(8)的情况下,结构体的大小分别是
A 16 24, 16 24
B 16 20, 16 20
C 16 16, 16 24
D 16 16, 24 24
正确答案: C
这题的考点就是内存对齐问题,在#pragma pack(4)的情况下,最大对齐数是4,在#pragma pack(8)的情况下,最大对齐数是8,所以在计算struct(Two)时,本来是20但要是对大对齐数的整数倍,所以就变成了24了
在32位cpu上选择缺省对齐的情况下,有如下结构体定义:
struct A
{
unsigned a : 19;
unsigned b : 11;
unsigned c : 4;
unsigned d : 29;
char index;
}
则sizeof(A)的值为
A 9
B 12
C 16
D 20
正确答案:C
这题考察的是对位段的认识,位段的成员可以是int
、unsigned int
、signed int
或者是cha
r 类型的整形家族,位段的成员名后边有一个冒号和一个数字。每次开辟4字节
或1字节
冒号后面接的是所需要的的比特位
#include
int main()
{
int n[][3] = { 10,20,30,40,50,60 };
int(*p)[3];
p = n;
cout << p[0][0] << "," << *(p[0] + 1) << "," << (*p)[2] << endl;
}
关于内存管理,以下有误的是( )(不定项选择)
A: malloc在分配内存空间大小的时候是以字节为单位
B: 如果原有空间地址后面还有足够的空闲空间用来分配,则在原有空间后直接增加新的空间,使得增加新空间后的空间总大小
是:newSize
C: 如果原有空间地址后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存,并把先前内存空间中的数
据复制到新的newSize大小的空间中,然后将之前空间释放
D: free函数的作用是释放内存,内存释放是标记删除,会修改当前空间的所属状态,并且会清除空间内容
E: 可以通过内存分配函数malloc(size_t)直接申请物理内存
正确答案:DE
free函数,作用是释放内存,内存释放是标记删除, 只会修改当前空间的所属状态,并不会清除空间内容
free释放的内存不一定直接还给操作系统,可能要到进程结束才释放。malloc不能直接申请物理内存,它申请的是虚拟内存
以上就是C语言的基础选择提了,如果这些题都做对了,那你的C语言基础还是很扎实的,希望我的文章对你有所帮助,欢迎点赞 ,评论,关注,⭐️收藏