100条常见的c语言代码汇总上篇2(类型转换错误,忽略返回值,浮点数精度问题,逻辑错误,指针操作错误)

11. 类型转换错误

        在C语言中,不恰当的类型转换可能导致数据丢失或程序行为异常。特别是在涉及不同大小或符号的整数类型,或者整数与浮点数之间的转换时,要特别小心。

代码案例:

#include <stdio.h>
int main() {unsigned int big_num = 4294967295U; // 最大的无符号32位整数int small_num = (int)big_num; // 错误的类型转换,数据丢失printf("%u\n", big_num); // 输出原始值printf("%d\n", small_num); // 输出转换后的值,可能会是负数return 0;
}

        在这个例子中,`big_num`是一个无符号32位整数,其值等于该类型可以表示的最大值。当我们试图将它转换为`int`类型时(假设`int`是32位有符号整数),数据会发生丢失,因为`int`类型无法表示这么大的正数,结果通常是得到一个负数。

12. 忽略返回值

        许多C语言函数都会返回一个值,这个值通常表示函数执行的状态或结果。忽略这些返回值可能会导致问题,特别是当函数失败时。

代码案例:

#include <stdio.h>
#include <stdlib.h>
int main() {FILE *file = fopen("file.txt", "r");if (file == NULL) {// 错误处理...}// 假设我们忽略了错误检查,并直接尝试读取文件int num;fscanf(file, "%d", &num); // 如果file是NULL,这里会导致崩溃printf("%d\n", num);// 忘记关闭文件// fclose(file);return 0;
}

        在这个例子中,我们打开了一个文件,但没有检查`fopen`是否成功。如果文件打开失败(例如,文件不存在),`fopen`会返回NULL,而`fscanf`尝试从NULL指针读取数据会导致程序崩溃。此外,我们还忘记了在读取完成后关闭文件,这可能会导致资源泄露。

13. 浮点数精度问题

        浮点数在计算机中的表示和计算是不精确的,这可能导致在比较浮点数或依赖精确计算时出现错误。

代码案例:

#include <stdio.h>
int main() {float a = 0.1;float b = 0.2;if (a + b == 0.3) { // 错误的浮点数比较printf("Equal\n");} else {printf("Not equal\n"); // 通常会输出这个,因为浮点数计算不精确}return 0;
}

        在这个例子中,我们试图比较两个浮点数的和是否等于某个值。然而,由于浮点数的精度问题,这种比较通常是不安全的。即使两个数在理论上应该相加得到某个结果,实际的计算结果可能会因为舍入误差而略有不同。

为了避免这些问题,程序员需要:

- 深入了解C语言中数据类型和类型转换的规则。

- 仔细检查所有函数调用,确保正确处理返回值。

- 对于浮点数,避免直接比较是否相等,而是检查它们是否“接近”相等,即它们的差的绝对值是否小于某个很小的阈值。

- 使用合适的错误处理机制来处理可能出现的异常情况。

14. 内存泄漏

        内存泄漏是C语言编程中常见的问题,它发生在程序分配了内存但没有适当地释放它时。这会导致程序消耗越来越多的内存,最终可能导致性能下降或程序崩溃。

代码案例:

#include <stdio.h>
#include <stdlib.h>
void leaky_function() {int *leak = (int *)malloc(sizeof(int)); // 分配内存*leak = 42; // 使用内存// 忘记释放内存
}
int main() {for (int i = 0; i < 10000; ++i) {leaky_function(); // 每次调用都会泄漏一块内存}return 0;
}

        在这个例子中,`leaky_function`分配了一块内存并将一个值赋给它,但在函数结束前没有释放这块内存。每次调用`leaky_function`都会泄漏一块内存,这将在循环中迅速积累,导致严重的内存泄漏。

15. 缓冲区溢出

        缓冲区溢出通常发生在向固定大小的缓冲区写入过多数据时。这可能导致数据覆盖到相邻的内存区域,可能破坏其他变量的值,或者更糟糕的是,执行恶意代码。

代码案例:

#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 10
void buffer_overflow() {char buffer[BUFFER_SIZE];strcpy(buffer, "This is a very long string that will overflow the buffer"); // 缓冲区溢出
}
int main() {buffer_overflow(); // 可能导致程序崩溃或其他未定义行为return 0;
}

        在这个例子中,`strcpy`函数尝试将一个长字符串复制到只有10个字符大小的`buffer`中。这会导致缓冲区溢出,可能会覆盖栈上的其他数据,从而引发程序崩溃或更严重的安全问题。

为了避免内存泄漏和缓冲区溢出,程序员应该:

- 在分配内存后始终记得释放它,尤其是在使用`malloc`、`calloc`或`realloc`等函数时。

- 使用安全的字符串操作函数,如`strncpy`代替`strcpy`,并确保目标缓冲区足够大以容纳要复制的数据。

- 在处理用户输入或外部数据时,要特别小心,避免未经检查的数据直接写入缓冲区。

- 使用工具和技术(如Valgrind、AddressSanitizer等)来检测内存泄漏和缓冲区溢出。

        C语言虽然强大且灵活,但也需要程序员对内存管理有深入的理解。通过遵循最佳实践和使用适当的工具,可以大大减少内存相关错误的发生。

16. 递归函数未设置终止条件

        递归函数是一种调用自身的函数,通常用于解决可以分解为更小子问题的问题。然而,如果递归函数没有设置正确的终止条件,它将无限循环,最终导致栈溢出。

代码案例:

#include <stdio.h>
void recursive_function() {printf("Calling recursive_function again...\n");recursive_function(); // 没有终止条件,导致无限递归
}
int main() {recursive_function(); // 程序将陷入无限递归,最终崩溃return 0;
}

        在这个例子中,`recursive_function`没有设置任何终止条件,因此它将无限次地调用自己,直到栈空间耗尽,程序崩溃。

17. 数组越界访问

        数组越界访问是另一个常见的错误,发生在程序试图访问数组元素时使用了超出数组实际大小的索引。这可能导致数据损坏或程序崩溃。

代码案例:

#include <stdio.h>
#define ARRAY_SIZE 5
int main() {int array[ARRAY_SIZE] = {1, 2, 3, 4, 5};printf("Element at index 5: %d\n", array[5]); // 数组越界访问,因为有效索引是0到4return 0;
}

        在这个例子中,`array`的大小定义为5,有效索引从0到4。然而,我们试图访问`array[5]`,这是一个越界访问,因为它超出了数组的有效范围。

18. 逻辑错误

        逻辑错误是指程序在执行时按照错误的逻辑路径执行,即使语法和内存管理都是正确的。这些错误通常是最难发现和调试的,因为它们涉及到程序员的逻辑思考和理解。

代码案例:

#include <stdio.h>
int main() {int a = 5;int b = 10;if (a > b) {printf("a is greater than b\n"); // 这个分支永远不会执行,因为a不大于b} else {printf("a is not greater than b\n"); // 这个分支将总是执行}return 0;
}

        在这个例子中,虽然程序在语法上是正确的,但它包含一个逻辑错误:`if`语句的条件检查`a`是否大于`b`,而实际上`a`是小于`b`的。因此,`if`语句内的代码块永远不会执行,这可能不是程序员的本意。

为了避免逻辑错误,程序员应该:

- 仔细规划和设计程序逻辑。

- 使用伪代码或流程图来明确表达算法。

- 编写单元测试来验证程序的不同部分是否按照预期工作。

- 在开发过程中进行彻底的代码审查。

        总之,编写无错误的C语言程序需要深入理解语言特性和良好的编程习惯。通过遵循最佳实践、使用调试工具、进行彻底的测试,并持续学习和改进,程序员可以减少错误并提高软件质量。

19. 类型转换错误

        在C语言中,类型转换是一个常见的操作,用于将一种类型的值转换为另一种类型。如果类型转换不当,可能会导致数据丢失、精度降低或程序行为异常。

代码案例:

#include <stdio.h>
int main() {double d = 3.14159;int i = (int)d; // 强制类型转换,丢失小数部分printf("Converted integer: %d\n", i); // 输出结果为3return 0;
}

        在这个例子中,我们试图将一个双精度浮点数`d`转换为整数`i`。由于使用了强制类型转换`(int)`,转换过程中会丢失小数部分,只保留整数部分。

20. 指针操作错误

        指针是C语言中的一个重要概念,允许程序员直接操作内存地址。然而,如果不正确地使用指针,可能会导致内存访问错误、程序崩溃或安全漏洞。

代码案例:

#include <stdio.h>
int main() {int x = 10;int *p = &x; // 指向x的指针int y = *p; // 通过指针访问x的值,y被赋值为10p++; // 增加指针的值,使其指向下一个整数位置int z = *p; // 访问未定义的内存位置,可能导致错误printf("Value of z: %d\n", z); // 输出可能是未定义的return 0;
}

        在这个例子中,我们创建了一个指向整数`x`的指针`p`,并通过`*p`正确地访问了`x`的值。然而,在增加指针`p`的值后,我们尝试通过`*p`访问一个未定义的内存位置,这可能导致未定义的行为,包括程序崩溃或数据损坏。

为了避免类型转换和指针操作错误,程序员应该:

- 仔细理解C语言中的类型转换规则,并避免不必要的类型转换。

- 始终确保指针指向有效的内存地址,并避免访问未定义或已释放的内存。

- 在使用指针进行算术运算时,要特别小心,确保不会超出有效内存范围。

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

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

相关文章

两重惊喜!奥特曼预告GPT-4和ChatGPT重大更新,Open AI要放大招

OpenAI在今天官宣13日&#xff08;下周一10点&#xff09;开启线上直播&#xff0c;将会展示全新的ChatGPT demo的演示以及GPT-4的重大更新&#xff01; OpenAI首席执行官Sam Altman在X上表示&#xff0c;这些的发布会&#xff0c;公司不会宣布下一代对话式人工智能GPT-5或人工…

ue引擎游戏开发笔记(37)——实现造成伤害

1.需求分析&#xff1a; 在游戏中已经能够射击&#xff0c;并且能得到实际的落点反馈&#xff0c;但本质上这种射击没有任何实际数值伤害&#xff0c;为射击添加实际的子弹伤害数值。 2.操作实现&#xff1a; 1.思路&#xff1a;ue本身函数FPointDamageEvent就可以解决&#x…

win11安装各银行的网银助手都无法打开,双击没反应?

大神贴 右键网银助手属性&#xff0c;在目标后面敲一下空格&#xff0c;输入**-runapp**&#xff0c;应用即可。 如图示例&#xff1a;

【HDFS】关于HDFS-17497:在commit block时更新quota

链接:https://github.com/apache/hadoop/pull/6765 Ticket标题:The number of bytes of the last committed block should be calculated into the file length。 HDFS里,一个在写入的文件可能包含多个commited状态的块。 但是计算文件大小的时候,最后一个commited block并…

英语写作中“特别(殊)的”“特定的”“具体的”special、particular、specific、concrete的用法

一、我们在学英语时special 这个单词出现频率高&#xff0c;耳濡目染&#xff0c;所以也爱用&#xff0c;其实有时候省掉special 显得语气平和&#xff0c;表达更地道。例如&#xff1a; We provide services for special people like the disabled. &#xff08;我们只服务残…

Vue3人员选择组件封装

一、组件介绍 人员组件在各系统的应用都是比较广泛的&#xff0c;因此可以将其封装为可配置的人员组件&#xff0c;根据不同角色权限显示对应的人员供选择&#xff0c;代码目前只是一部分&#xff0c;需要源码的私聊。 二、直接上代码 use.vue 父组件 <div class&q…

Git那些事-如何撤销暂存区的文件

在Git的操作中&#xff0c;有时在将本地仓库中已修改的文件添加到暂存区时&#xff0c;会出现添加了"错误"文件的情况&#xff08;这里的错误指的是这些文件我们并不需要上传到远程仓库&#xff09;。这就需要我们将添加到暂存区中"错误"的文件恢复到本地仓…

BUU-[极客大挑战 2019]Http

考察点 信息收集 http构造请求数据包 题目 解题步骤 参考文章&#xff1a;https://zhuanlan.zhihu.com/p/367051798 查看源代码 发现有一个a标签&#xff0c;但是οnclick"return false"就是点击后不会去跳转到Secret.php的页面 所以我就自己拼接url http://no…

【鱼眼+普通相机】相机标定

一、简介 本文提供了鱼眼及普通相机的标定python版源码,调用opencv的接口,原理为张正友标定法。这里不过多赘述,话不多说无套路直接上源码,亲测有效,搬走即用。 注: 需准备一个标定版,在此网站下载打印出来即可;例如12x8的棋盘格内角点为11x7.二 、源码 2.1 鱼眼相机…

音频—WAV格式及写入wav文件代码实现

1.RIFF规范 FIFF 是 Resource Interchange File Format&#xff08;资源交换文件格式&#xff09;的简称。RIFF 是一种文件格式规范&#xff0c;用于在计算机系统之间交换和存储多媒体资源。WAV 文件格式是 Microsoft 的 RIFF 规范的一个子集。 RIFF 规则定义了文件的结构和数…

【案例分享】校园服务小程序开发经验和主要功能,引领校园生活新方式

随着移动互联网的普及&#xff0c;学生们对于校园生活的需求也在不断增长。校园圈子、校园跑腿、校园外卖、校园服务等小程序等应用应运而生&#xff0c;为学生们提供了更加便捷、高效的生活方式。那么&#xff0c;如何开发一款能够满足学生需求的校园服务小程序呢&#xff1f;…

react18封装公共请求函数

如果里面要处理比如token过期&#xff0c;跳转登录这种情况的话&#xff0c;官方又说组件外不允许使用Hooks函数&#xff0c;这里可以这样做 使用redux 并新建一个store/index.ts import { configureStore, combineReducers } from reduxjs/toolkit import counterRouter fro…

JavaScript创建日期

创建日期 在JavaScript中创建日期有四种方法 ● 使用new Date() const now new Date(); console.log(now);● 直接输入月、日、年、时间 console.log(new Date(Aug 02 2024 18:05:41));● 也可以输入年月日 console.log(new Date(December 24, 2015));● 直接按照年、月、…

用于接收参数的几个注解

了解四种主要请求方法的传参格式 GET方法&#xff1a; 参数通常通过URL的查询字符串&#xff08;query string&#xff09;传递&#xff0c;形式为key1value1&key2value2。示例&#xff1a;http://example.com/api/resource?key1value1&key2value2 POST方法&#xf…

C++入门系列-析构函数

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 析构函数 概念 析构函数&#xff0c;与构造函数功能相反&#xff0c;析构函数不是完成对对象本身的销毁&#xff0c;局部对象销毁工作是由编译器完成的&#xff0c;而对象在销…

基于深度学习的人体关键点检测与姿态识别

文章目录 源码下载地址&#xff1a; 源码地址在视频简介中 深度学习人体关键点检测&#xff0c;姿态识别 界面效果&#xff1a; 界面代码&#xff1a; from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * f…

OGG几何内核开发-BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound比较

最近在与同事讨论BRepAlgoAPI_Fuse与BRep_Builder.MakeCompound有什么区别。 一、从直觉上来说&#xff0c;BRepAlgoAPI_Fuse会对两个实体相交处理&#xff0c;相交的部分会重新的生成相关的曲面。而BRep_Builder.MakeCompound仅仅是把两个实体组合成一个新的实体&#xff0c;…

Apache Sqoop:高效数据传输工具搭建与使用教程

目录 引言一、环境准备二、安装sqoop下载sqoop包解压文件 三、配置Sqoop下载mysql驱动拷贝hive的归档文件配置环境变量修改sqoop-env.sh配置文件替换版本的commons-lang的jar包 验证Sqoop安装查看Sqoop版本测试Sqoop连接MySQL数据库是否成功查看数据库查看数据表去除警告信息 四…

【免费】在线识别通用验证码接口

模块优势价格5元1000次&#xff0c;每天免费100次api文档支持 使用量小的完全够用了 <?phpfunction Post_base64($base64_str){$url http://api.95man.com:8888/api/Http/Recog?Taken41******QK&imgtype1&len0 ; $fields array( ImgBase64>$base64_str); $ch…

031.下一个排列Java实现

题意 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地&#…