C语言阶段的题目解析

news2024/11/25 22:34:20

前言

我们C语言已经学习的差不多了,但是C语言之中存在的一些问题与难点我们还不一定能够又快又好地解决,为了夯实我们的基础,我们来练习几道稍微有点难度的C语言习题吧

例题一

题目

int main(void)
{
	unsigned char i = 7;
	int j = 0;
	for (; i > 0; i -= 3)
	{
		++j;
	}
	printf("%d\n", j);
	return 0;
}

题解

在开始解题之前,我们需要知道 unsigned char 类型的取值范围是 0~255

所以 i 的取值不可能是一个负数;

所以跳出循环的条件只有可能是 i=0 ;

我们来画一个图分析一下 unsigned char 类型的变量的取值范围的变化过程:

已知 i 的初始值是7,所以当 i 减到1的时候下一次执行-3操作的时候得到的值是254

因为:254 / 3 = 84……2,此时 i 在减去了84个3之后执行 -3 操作得到的值仍然不是0而是2,所以我们还需要向下执行 -3 操作,此时得到的值是255

因为:255 / 3 = 85 ,此时255是3的倍数在执行了85次 -3 操作以后i的值成功变成了0,此时也就跳出了循环;

所以 j 的值就应该是 2 + 1 + 84 + 1 + 85 = 173 次

例题二

题目

以下那个选项一定可以将flag的第二个bit位置0?

A.flag &=~2

B.flag |= 2

C.flag ^= 2

D.flag >>= 2

题解

我们发现:原题目中与flag执行操作的数都是2

因为2是一个正数,所以2的原码就是补码

所以2的二进制补码为:

00000010

而2的反码就是:

11111101

我们直接带入一个特殊的值就可以解决问题:

假设我们有一个二进制的数:

11111111

假设我们要把第二个bit位置为0,我们必须要保证与这个二进制数按位与(&)的二进制数的第二个bit位必须是0

而且其它位上的值不能改变,所以除了第二个bit位,其它位置上的数都必须是1

此时这个二进制数为:

11111101

这个二进制数的二进制形式刚好符合2的反码,所以我们知道这个题目选 A

题目三

题目

struct One
{
	double d;
	char c;
	int i;
};

struct Two
{
	char c;
	double d;
	int i;
};

计算在#pragma pack(4)和#pragma pack(8)的情况下,结构体大小分别是?

题解

该题目只需要把图画出来,就可以很轻松的解决问题

由图片可以知道:

在#pragma pack(4)和#pragma pack(8)的情况下,结构体大小分别是:

16                16                16                24

例题四

题目

在上下文和头文件均正常的情况下,下列程序的输出结果是:

int x = 1;
do
{
	printf("%2d\n".x++);
} while (x--);

A.1

B.无任何输出

C.2

D.陷入死循环

题解

因为题目中打印的是x++,x++是先使用后+1,所以我们就可以知道先打印出的值是1打印完成以后,x执行++操作变成了2

接着我们进入while循环之中的判断,此时条件是x--,因为x是先使用后--,所以判断时x的值是2,而判断完以后x执行--操作变成了1

我们通过分析知道了,x的取值会一直在1和2之中跳动,所以循环永远不会结束

故选:D

例题五

题目

下列程序执行后c输出的结果为?(32位)

void main()
{
	int a = -3;
	unsigned int b = 2;
	long c = a + b;
	printf("%ld\n", c);
}

A.-1

B.4294967295

C.0x7FFFFFFF

D.0xFFFFFFFF

题解

在解题的时候,我们需要知道 -3 的原码、反码、补码

-3 的原码:10000000000000000000000000000011

10000000000000000000000000000011

-3 的补码:11111111111111111111111111111101

11111111111111111111111111111101

2的补码:0000000000000000000000000000010

00000000000000000000000000000010

c的二进制序列:11111111111111111111111111111111

11111111111111111111111111111111

c的补码:10000000000000000000000000000001

10000000000000000000000000000001

此时打印出来的值就是-1

所以答案选:A

例题6

题目

int fun(int a)
{
	a ^= (1 << 5) - 1;
	return a;
}

fun(21)的运行结果是?

A.10

B.5

C.3

D.8

题解

我们知道,1的补码是:

00000001

所以1向左移动5位之后为:

00100000

该二进制位-1得到的是:

00011111

因为我们传入的参数a是21,所以我们应该用21去异或这个值:

00010101
00011111

此时得到的二进制序列为:

00001010

所以打印出来的值是:10

故答案是:A

例题7

题目

下列关于C/C++的宏定义,不正确的是?

A.宏定义不检查函数正确性,会有安全隐患

B.宏定义的常量更容易理解,如果可以使用宏定义常量的话,要避免使用const常量

C.宏的嵌套定义过多会影响程序的可读性,而且很容易出错

D.相对于函数调用,宏定义可以提高程序的运行效率

题解

A、C、D三个选项正确

我们知道,定义一个常量有两种方法:

#define M 10
const int m = 10;

C语言之中,const修饰的变量叫常变量

C++中const修饰的对象就是一个常量

所以在C++中能使用const定义常量就尽量使用const修饰常量,C语言中则相反

所以答案是:B

例题8

题目

#define N 3+1
#define Y(n)((N+1)*n)

执行 z=2*(N+Y(5+1)) 后,z的值为?

A.60

B.190

C.248

D.上述答案都不对

题解

在解决这个问题的时候,我们需要注意:不能提前把N的值和表达式的值计算出来,需要将表达式整体代入,然后按照运算的先后顺序进行运算

此时z可以转化为:z = 2 * (3+1+( (5)*5 +1)

这样计算出来的值就是60

所以答案就是:D

例题9

题目

char a; int b; float c; double d;

则表达式 a * b + d - c 的值的类型是?

A.float

B.int

C.char

D.double

题解

我们知道:a是char类型的,b是int类型的;

所以在计算的时候,char类型的a需要整型提升为int类型

int类型的值乘一个int类型的值结果也是一个int类型的值

当a*b得到的int类型的值与double类型的d计算的时候:

int类型的值会被强制算术转换为double类型的值;

所以a*b+d得到的值就是double类型的值;

同理,float类型的c在与double类型的值计算的时候也会算术转换为double类型的值

所以 a*b+d-c 的值就是double类型的

所以答案选:D

编程题1:

题目

对于一个较大的整数N(1<=N<=2,000,000,000)

比如说489275936,我们常常需要一位一位的数这个数是几位数,但是如果在这个数每三位加上一个“,”,它就会更加易于朗读:489,275,936

请写出一个程序来完成这个内容

题解

我们先来分析一下:(以12345为例子)

1.我们需要采取从右往左处理的顺序,因为如果使用从左往右处理的顺序还需要判断

2.因为我们采取的是从右往左处理的顺序,所以我们需要先提取出数的最后一位5

我们知道,对数采取 %10可以提取出最后一个位的数字,对一个数采取 /10 操作可以去掉最后一个位上面的数字

一直采取 %10 和 /10 操作,最后n的取值就会变成0

3.当我们每次处理完3个数字的时候就加上一个“,”

4.我们可以把提取出来的数放到一个字符数组里面去,当n=0跳出循环的时候再倒着打印数组里面的内容

5.我们每次%10之后的取值是数字5,因为数组是字符数组,此时我们只需要给数字5加上一个'0',就可以变成字符'5'

6.每放三位,就添加一个“,”,此时我们需要定义一个变量k,用来判断是否处理到了3个数。注意:k == 0的时候 %3 也是0,要排除这个情况

7.当我们处理完数组的时候,此时i指向数组最后一个元素的下一个元素所以我们还要加入一个i--操作,让它指向数组里面的最后一个元素

有了这些思路,我们就可以很轻松的写出代码:

int main(void)
{
	char arr[20] = { 0 };
	int N = 0;
	scanf("%d", &N);
	int k = 0;
	int i = 0;
	while (N)
	{
		if (k != 0 && k % 3 == 0)
		{
			arr[i++] = ',';
		}
		arr[i++] = N % 10 + '0';
		N = N / 10;
		k++;
	}
	for (i--; i >= 0; i--)
	{
		printf("%c", arr[i]);
	}
	return 0;
}

编程题2

题目

题解

我们先来分析一下:

1.再输入字符串的时候最好不使用scanf函数,因为scanf函数在遇到空格的时候就不会再往后读取了,此时我们需要用到gets函数

2.我们需要逐步判断arr2字符数组里面的每一个元素,如果arr1数组里面有这个元素,就把它删除

   思路一:在删除完一个元素以后,我们要把这个元素以后的所有元素全部往前挪

   思路二:我们遍历arr1数组,看arr1数组里面的每个元素在不在arr2数组中存在,如果在arr2数组中存在,就不打印出来,反之则打印

(因为思路二的效率更高,所以我们采用思路二)

3.当arr1数组遍历到 \0 的时候,跳出循环

有了这些理论基础,我们就可以写出代码如下:

int is_exist(char ch, char arr[])
{
	int i = 0;
	while (arr[i])
	{
		if (ch == arr[i])
		{
			return 1;
		}
		i++;
	}
	return 0;
}


int main(void)
{
	char arr1[200] = { 0 };
	char arr2[200] = { 0 };
	gets(arr1);
	gets(arr2);

	int i = 0;
	while (arr1[i])
	{
		if(is_exist(arr1[i], arr2) == 0)
		{
			printf("%c", arr1[i]);
		}
		i++;
	}
	return 0;
}

上述代码中的is_exist其实可以用库函数实现,库函数中有一个函数叫做strchr

如果出现了某个字符,就返回这个字符的地址,如果没有出现这个字符,就会返回NULL

strchr的头文件是<string.h>

所以此时我们还有一种写法:

#include <stdio.h>
#include <string.h>
int main(void)
{
	char arr1[200] = { 0 };
	char arr2[200] = { 0 };
	gets(arr1);
	gets(arr2);

	int i = 0;
	while (arr1[i])
	{
		if(strchr(arr2, arr1[i]) == NULL)
		{
			printf("%c", arr1[i]);
		}
		i++;
	}
	return 0;
}

如果此时我们使用scanf也可以实现,只不过格式有点复杂:

int main(void)
{
	char arr1[200] = { 0 };
	char arr2[200] = { 0 };
	scanf("%[^\n]s", arr1);
	getchar();
	scanf("%[^\n]s", arr2);

	int i = 0;
	while (arr1[i])
	{
		if(strchr(arr2, arr1[i]) == NULL)
		{
			printf("%c", arr1[i]);
		}
		i++;
	}
	return 0;
}

此时需要用getchar清除缓冲区,会比较复杂,难以理解,所以不建议使用

结尾

本节我们练习了9个选择题和2个编程题,有助于我们夯实C语言的基础,查漏补缺,那么本节的内容就到此结束了,希望可以给您带来帮助,谢谢您的浏览!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1632415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

织梦云端:网络信号原理的艺术解码

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《织梦云端&#xff1a;网络信号原理的艺术解码》&#xff0c;在这篇文章中&#xff0c;你将会学习到网络信号原理以及应用&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图…

MQTT数据传输Payload的常见格式介绍

使用MQTT client过程中看到常见的数据格式&#xff1a; 下面是介绍 Plaintext&#xff08;纯文本&#xff09; 介绍&#xff1a;纯文本编码是最基本的编码形式&#xff0c;它使用标准的ASCII或Unicode字符来表示数据。这种编码格式是人类可读的&#xff0c;因为它直接表示文本信…

centos 7使用源码编译安装Python 3.12.2(最新版本)

&#xff08;一&#xff09;、说明 在centos 7上&#xff0c;默认安装出来的python是&#xff1a;2.7.5版本 1.查看python版本&#xff1a; python --version 2.通过yum安装出来的&#xff0c;适合当前操作系统的&#xff0c;最新的python版本是&#xff1a;3.6.8 python3…

C#队列(Queue)的基本使用

概述 在编程中&#xff0c;队列&#xff08;Queue&#xff09;是一种常见的数据结构&#xff0c;它遵循FIFO&#xff08;先进先出&#xff09;的原则。在C#中&#xff0c;.NET Framework提供了Queue<T>类&#xff0c;它位于System.Collections.Generic命名空间下&#x…

Spring事务回滚核心源码解读

记一次Springboot事务超时不回滚的分析过程 在Springboot中&#xff0c;我用的xml进行事务管理&#xff0c;DataSourceTransactionManager作为事务管理器&#xff0c;配置了事务控制在Service层&#xff1b;在事务管理器中&#xff0c;配置了defaultTimeout事务超时时间为5秒&…

RK3588 - RKNN(Rockchip 神经处理单元)的逆向工程

本文翻译自https://jas-hacks.blogspot.com/2024/02/rk3588-reverse-engineering-rknn.html RK3588 NPU 的内部操作和功能主要隐藏在名为RKNPU2的闭源 SDK 中。由于对大型语言模型 (LLM) 的兴趣以及对transform模型最佳矩阵乘法的追求&#xff0c;想了解 RKNPU SDK 新引入的矩阵…

Jetpack Compose简介

文章目录 Jetpack Compose简介概述声明式UI和命令式UIJetpack Compose和Android View对比Compose API设计原则一切皆为函数组合优于继承单一数据源 Jetpack Compose和Android View关系使用ComposesetContent()源码ComposablePreview Jetpack Compose简介 概述 Jetpack Compos…

数据结构-二叉搜索树(BST)

目录 什么是二叉搜索树 二叉搜索树的特性 (1)顺序性 (2)局限性 二叉搜索树的应用 二叉搜索树的操作 (1)查找节点 (2)插入节点 (3)删除节点 (4)中序遍历 什么是二叉搜索树 如图所示&#xff0c;二叉搜索树&#xff08;binary search tree&#xff09;满足以下条件。…

Unity 递归实现数字不重复的排列组合

实现 private void Permutation(List<int> num, int leftIndex, List<string> strs) {if (leftIndex < num.Count){for (int rightIndex leftIndex; rightIndex < num.Count; rightIndex){Swap(num, leftIndex, rightIndex);Permutation(num, leftIndex 1…

【深度学习】【Lora训练1】StabelDiffusion,Lora训练过程,秋叶包,Linux,SDXL Lora训练

文章目录 一、环境搭建指南二、个性化安装流程三、启动应用四、打开web五、开始训练 19.27服务器 一、环境搭建指南 打造一个高效且友好的开发环境&#xff1a; 项目源码获取&#xff1a; 通过以下命令轻松克隆项目及所有子模块至您的Linux系统&#xff1a; git clone --recu…

workminer之dht通信部分

workminer是通过SSH爆破传播的挖矿木马&#xff0c;感染后会释放xmrig挖矿程序利用主机的CPU挖取北方门罗币。该样本能够执行特定的指令&#xff0c;指令保存在一个配置文件config中&#xff0c;config文件类似于xml文件&#xff0c;里面有要执行的指令和参数&#xff0c;样本中…

服务注册与发现Eureka、Zookeeper、Consul 三个注册中心的异同点(CAP理论)

Eureka Eureka是由Netflix开源的一个服务注册和发现组件&#xff0c;它主要用于构建高可用、分布式系统的基础设施中。Eureka的服务器端被称为Eureka Server&#xff0c;客户端则是那些需要注册的服务。Eureka具有以下特点&#xff1a; 高可用性&#xff1a;Eureka支持多节点…

小米汽车充电枪继电器信号

继电器型号&#xff1a; 参考链接 小米SU7&#xff0c;便捷充放电枪拆解 (qq.com)https://mp.weixin.qq.com/s?__bizMzU5ODA2NDg4OQ&mid2247486086&idx1&sn0dd4e7c9f7c72d10ea1c9f506faabfcc&chksmfe48a110c93f2806f6e000f6dc6b67569f6e504220bec14654ccce7d…

Linux网络开发基础知识

一个网络服务器的简单实现 项目需求 实现回声服务器的客户端/服务器程序&#xff0c;客户端通过网络连接到服务器&#xff0c;并发送任意一串英文信息&#xff0c;服务器端接收信息后&#xff0c; 将每个字符转换为大写并回送给客户端显示。 eoch_client.c #include <arpa/i…

Android双向认证配置过程

1&#xff08;可以绕过&#xff09;准备过程 为了让这个教程可以一直复用&#xff0c;打算直接写一个双向认证的APP作为素材。 工具&#xff1a; ●protecle&#xff08;签名文件转换&#xff09; ●keytool&#xff08;java自己就有&#xff09; ●openssl&#xff08;apache里…

前端canvas项目实战——在线图文编辑器(九):逻辑画布

目录 前言一、 效果展示二、 实现步骤1. 调整布局&#xff0c;最大化利用屏幕空间2. 添加逻辑画布3. 添加遮罩4. 居中显示逻辑画布5. 一个容易被忽视的bug点 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了一组通用的功能按钮&#xff1a;复制、删除、锁定…

LeetCode-hot100题解—Day5

原题链接&#xff1a;力扣热题-HOT100 我把刷题的顺序调整了一下&#xff0c;所以可以根据题号进行参考&#xff0c;题号和力扣上时对应的&#xff0c;那么接下来就开始刷题之旅吧~ 1-8题见LeetCode-hot100题解—Day1 9-16题见LeetCode-hot100题解—Day2 17-24题见LeetCode-hot…

httpClient提交报文中文乱码

httpClient提交中文乱码&#xff0c;ContentType类型application/json 指定提交参数的编码即可 StringEntity se new StringEntity(paramBody.toJSONString(),"UTF-8");se.setContentType("application/json");context.httpPost.setHeader("Cookie&…

Go-Zero从0到1实现微服务项目开发(二)

前言 书接上回&#xff0c;继续更新GoZero微服务实战系列文章。 上一篇被GoZero作者万总点赞了&#xff0c;更文动力倍增&#xff0c;也建议大家先看巧一篇&#xff0c;欢迎粉丝股东们三连支持一波&#xff1a;Go-zero微服务快速入门和最佳实践&#xff08;一&#xff09; 本…

Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模板

Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模板 2024 年 4 月版本更新&#xff0c;现在自动运行 sysprep&#xff0c;支持 ESXi Host Client 部署 请访问原文链接&#xff1a;Windows Server 2022 OVF, updated Apr 2024 (sysin) - VMware 虚拟机模…