这些基础的C语言选择题,不知道你能不能拿满分

文章目录

  • 大小端与传参
  • 类型范围
  • 逻辑判断
  • 进制数与格式化输出
  • 计算次数
  • 常量指针与指针常量
  • 字符指针与字符数组
  • 指针与数组
  • 内存对齐
  • 动态内存分配

大小端与传参

假设在一个 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
这题的考点就是大小端字节序与函数传参顺序
关于大小端问题就是数据在内存中的存储顺序
大端模式(大端字节序):数据的低字节保存在内存的高地址中,高字节保存在低地址
小端模式(小端字节序):低位低地址高位高地址
下图这就是标准的小端存储
这些基础的C语言选择题,不知道你能不能拿满分_第1张图片这些基础的C语言选择题,不知道你能不能拿满分_第2张图片

还有一个就是函数传参顺序,调用printf函数需要压栈建立函数栈帧,函数传参是从右向左的,下面就可以看到,不管a,b,c是谁先定义,都只与传参顺序有关。栈底是高地址,栈顶是低地址

这些基础的C语言选择题,不知道你能不能拿满分_第3张图片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

正确答案:D
这题的考点就是类型的范围,char类型是8位,也就是-128~127
所以a+=27后a的值为-128
这些基础的C语言选择题,不知道你能不能拿满分_第4张图片

逻辑判断

以下程序的输出结果是

#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
这些基础的C语言选择题,不知道你能不能拿满分_第5张图片

以下程序的运行结果是()

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
这些基础的C语言选择题,不知道你能不能拿满分_第6张图片

计算次数

求函数返回值,输入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
这些基础的C语言选择题,不知道你能不能拿满分_第7张图片

假设函数原型和变量说明如下,则调用合法的是( )

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型数组
这些基础的C语言选择题,不知道你能不能拿满分_第8张图片

数组 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
这题考察的是对位段的认识,位段的成员可以是intunsigned intsigned int 或者是 char 类型的整形家族,位段的成员名后边有一个冒号和一个数字。每次开辟4字节1字节
冒号后面接的是所需要的的比特位
这些基础的C语言选择题,不知道你能不能拿满分_第9张图片

#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语言基础还是很扎实的,希望我的文章对你有所帮助,欢迎点赞 ,评论,关注,⭐️收藏

这些基础的C语言选择题,不知道你能不能拿满分_第10张图片

你可能感兴趣的:(C++刷题笔记,数据结构,开发语言,c语言)