C 的16个大坑,你能躲过几个?

首先说下C 和C语言有什么区别?分享一个我在知乎上看见的回答:

  • C ≈ C with classes, C with STL

  • C:面向机器编程

  • C :面向编译器编程

C 有个很重要的特性叫RAII,个人认为可以多多使用,相当方便。

言归正传,下面我一个一个的列出来C 使用过程中常见的坑:

无符号整数的错误使用

for (unsigned int i = 10; i >= 0; --i) { ... }

上面这段代码会发生什么? 会死循环,这里要注意下无符号整数的使用。

容器的size()返回类型是无符号整数

std::vector 
vec;vec.push_back(1);
for (auto idx = vec.size(); idx >= 0; idx--) {cout << "===== \n";
}

这段代码依旧会出现死循环,原因参考上一条。

STL遍历删除时注意迭代器失效问题

void erase(std::vector<int> &vec, int a) {    for (auto iter = vec.begin(); iter != vec.end();) { // 这个正确        if (*iter == a) {            iter = vec.erase(iter);        } else {              iter;        }    }for (auto iter = vec.begin(); iter != vec.end();   iter) {  // error        if (*iter == a) {            vec.erase(iter); // error        }    }}

std::list排序使用自己的成员方法

一般的容器排序都使用std::sort(),但是list特殊。

int main() {std::list list{1, 2, 3, 2};    list.sort();    // std::sort(list.begin(), list.end());    for (auto i : list) {std::cout << i << " ";    }    std::cout << "\n";    return 0;
}

注释用/**/,而不是//

注释用/**/,可能会出问题。原因:utf-8和ANSC(GB2312)编码混乱后,中文注释就乱码了,乱码中藏着 */,匹配错了,导致IDE实际注释的部分并非肉眼所见,定位极其困难,常见于Windows中。

不要返回局部变量的指针或引用

char* func() {char a[3] = {'a', 'b', 'c'};    return a;
}

栈内存容易被污染。

浮点数判断是否相等问题

float f;
if (f == 0.2) {} // 错误用法
if (abs(f - 0.2) < 0.00001) {} // 正确用法

vector clear和swap问题

清空某个vector,可以使用swap而不是其clear方法,这样可以更早的释放vector内部内存。

vector vec;
vector().swap(vec);
vec.clear();

vector问题

尽量不要在vector中存放bool类型,vector为了做优化,它的内部存放的其实不是bool。

条件变量

条件变量的使用有两大问题:信号丢失和虚假唤醒,相当重要。

类型转换

在C 中尽量使用C 风格的四种类型转换,而不要使用C语言风格的强制类型转换。

std::thread的使用

一定要记得join或这detach,否则会crash。

void func() {}
int main() {std::thread t(func);    if (t.joinable()) {t.join(); // 或者t.detach();     }    return 0;
}

enum使用

尽量使用enum class替代enum,enum class 是带有作用域的枚举类型。

空指针使用nullptr而不是NULL

void func(char*) {    cout << "char*";}void func(int) {    cout << "int";}
int main() {     func(NULL); // 编译失败 error: call of overloaded ‘func(NULL)’ is ambiguous    func(nullptr); // char*    return 0;}

std::remove的使用

这个remove其实并没有真正的删除元素,需要和erase配合使用,跑一下这段代码就知道啦。

bool isOdd(int i) { return i & 1; }
void print(const std::vector<int>& vec) {    for (const auto& i : vec) {        std::cout << i << ' ';    }    std::cout << std::endl;}
int main() {    std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};    print(v);std::remove(v.begin(), v.end(), 5);  // error    print(v);v.erase(std::remove(v.begin(), v.end(), 5), v.end());    print(v);v.erase(std::remove_if(v.begin(), v.end(), isOdd), v.end());    print(v);}

全局变量初始化问题

不同文件中的全局变量初始化顺序不固定,全局变量尽量不要互相依赖,否则由于初始化顺序不固定的问题,可能会导致bug产生。

END

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

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

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

相关文章

python占位符怎么输入_python占位符怎么输入

占位符&#xff0c;顾名思义就是插在输出里站位的符号。占位符是绝大部分编程语言都存在的语法&#xff0c; 而且大部分都是相通的&#xff0c; 它是一种非常常用的字符串格式化的方式。1、常用占位符的含义s : 获取传入对象的__str__方法的返回值&#xff0c;并将其格式化到指…

java 性能调优_Java性能调优调查结果(第三部分)

java 性能调优这是本系列文章的第三篇&#xff0c;我们将分析2014年10月进行的调查的结果。如果您尚未这样做&#xff0c;我建议从本系列的前两篇文章开始&#xff1a; 问题严重性分析和监视域分析 。 这篇文章着重于故障排除/根本原因检测。 本调查部分的背景&#xff1a;意识…

不懂指针类型,7个例子给你讲明白

1. int va;这是一个整型变量&#xff0c;32位CPU的话&#xff0c;占有32个bite2. int *va;这是一个整型指针变量&#xff0c;用于存放一个整型变量的地址&#xff0c;3. int **va;这是一个整型的二级指针&#xff0c;用于存放一个内存的地址&#xff0c;该地址对应的内存中存放…

linux ffmpeg yum源,ffmpeg最新的yum源地址及视频去logo

一&#xff1a;ffmpeg 最新yum源cat /etc/yum.repo.d/atrpms.repo[atrpms]nameRed Hat Enterprise Linux $releasever - $basearch - ATrpmsfailovermethodprioritybaseurlhttp://dl.atrpms.net/el$releasever-$basearch/atrpms/stableenabled1gpgcheck0gpgkeyfile:///etc/pki/…

Tomcat与Netty比较

Tomcat介绍Tomcat支持的协议Tomcat的优缺点Netty介绍Netty支持的协议Netty的优点和缺点Tomcat和Netty的区别Tomcat和Netty的应用场Tomcat和Netty来处理大规模并发连接的优化Tomcat与Netty的网络模型的区别Tomcat与Netty架构设计拓展 Tomcat介绍 Tomcat是一个免费的、开放源代码…

spring 项目集成配置_Spring重试–与项目集成的方式

spring 项目集成配置如果您需要在代码中实现健壮的重试逻辑&#xff0c;一种行之有效的方法是使用spring重试库。 我的目的不是要展示如何使用spring retry项目本身&#xff0c;而是要演示将其集成到代码库中的不同方式。 考虑一种服务来调用外部系统&#xff1a; package re…

redis 内存不足 排查_排查redis占用内存达90%以上

帮别人排查一个问题,项目还没上线但redis占用内存很高。思路如下&#xff1a;1、登陆redis控制台&#xff0c;首先用 keys * 获取所有的key> keys *x:x:ax:x:bx:x:c发现key也就十来个&#xff0c;用 TYPE x:x:a 发现a是一个list数据类型用lrange命令查看list中指定索引的值用…

C或C 如何通过程序执行shell命令并获取命令执行结果?

1 应用场景最近在实际程序开发中&#xff0c;需要通过程序执行 shell 命令&#xff0c;并获取命令输出内容。但是系统自带的 system 只能返回命令执行成功与否&#xff0c;不能捕获命令输出。2 扩展性由于应用场景本就广泛&#xff0c;因此扩展性较好。此函数可以执行任意命令&…

linux centos7安装ngix,centos7 环境下安装nginx--Linux

本文将要为您介绍的是centos7 环境下安装nginx--Linux,具体完成步骤:一、安装前需要的编译环境准备1、安装makeyum install -y gcc automake autoconf libtool make2、安装gcc、gcc-cyum install -y gcc gcc-c3、关闭防火墙iptables -F4、关闭selinux#临时关闭&#xff1a;sete…

16进制数组转成10进制 qt_QT 十六进制字符串转化为十六进制编码

/*************************************************Function: hexStringtoByteArray()Description:十六进制字串转化为十六进制编码Calls: formatString()Called By:Input: hex->待转化的十六进制字串Output: NULLReturn: QByteArrayOthers: NULL************************…

primefaces_使用PrimeFaces开发数据导出实用程序

primefaces我的日常工作涉及大量使用数据。 我们使用关系数据库来存储所有内容&#xff0c;因为我们依赖于企业级的数据管理。 有时&#xff0c;具有将数据提取为简单格式&#xff08;例如电子表格&#xff09;的功能很有用&#xff0c;以便我们可以按需进行操作。 这篇文章概述…

如何优雅地实现判断一个值是否在一个集合中?

如何判断某变量是否在某个集合中&#xff1f;注意&#xff0c;这里的集合可能并不是指确定的常量&#xff0c;也可能是变量。版本0#include int main(){int a 5;if(a 1 || a 2 || a 3 || a 4 || a 5){std::cout<<"find it"<<std::endl;}return 0;…

c语言所有关键字作用,void_C语言void关键字详解

void类型修饰符(type specifier)表示“没有值可以获得”。因此&#xff0c;不可以采用这个类型声明变量或常量。void 类型可以用于下面各小节所描述的目的。void用于函数声明没有返回值的函数&#xff0c;其类型为 void。例如&#xff0c;标准库函数 perror() 被声明为以下原型…

jvmti_拥有您的堆:使用JVMTI迭代类实例

jvmti今天&#xff0c;我想谈一谈我们大多数人每天都不会看到和使用的另一种Java&#xff0c;更确切地说&#xff0c;是有关较低级别的绑定&#xff0c;一些本机代码以及如何执行一些小的魔术。 尽管我们不会在JVM上找到真正的魔力源&#xff0c;但是在单个帖子的范围内可以实现…

babylonjs 分部加载模型_BabylonJS加载OBJ或STL模型文件实例

JavaScript语言&#xff1a;JaveScriptBabelCoffeeScript确定var canvas document.getElementById("renderCanvas");var engine new BABYLON.Engine(canvas, true);var createScene function() {// This creates a basic Babylon Scene object (non-mesh)var scen…

骚操作:利用强弱符号制作插件库

当有强符号和弱符号时&#xff0c;选择使用强符号那么我们正可以利用这个原则做以下事情&#xff1a;定义为弱符号&#xff0c;如果是弱符号&#xff0c;使用默认行为如果链接了库&#xff0c;是强符号&#xff0c;则使用外部定义行为以此来实现一个类似插件的功能。通俗一点说…

c语言里 t是什么作用,c语言里的\t是什么意思

c语言里的&#xff3c;t是什么意思以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;c语言里的&#xff3c;t是什么意思正宗叫法是“水平制表符”&#xff0c;就是在输出媒体上水平跳过多个空格…

boot jersey_Jersey和Spring Boot入门

boot jersey除了许多新功能&#xff0c;Spring Boot 1.2还带来了Jersey支持。 这是吸引喜欢标准方法的开发人员的重要一步&#xff0c;因为他们现在可以使用JAX-RS规范构建RESTful API&#xff0c;并将其轻松部署到Tomcat或任何其他Springs Boot支持的容器中。 带有Spring平台的…

mime类型是什么 node_Node.js - 文件系统获取文件类型

我需要借助node.js来获取文件的文件类型以设置内容类型。我知道我可以很容易地检查文件扩展名&#xff0c;但我也有没有扩展名的文件&#xff0c;其内容类型应该是image/png,text/html aso。Node.js - 文件系统获取文件类型这是我的代码(我知道这并没有太大的意义&#xff0c;但…

函数或全局变量重复定义时会怎样?

可能有些朋友第一反应是&#xff0c;那肯定是编译不过喽&#xff1a;// fun.c #include void func() {printf("编程珠玑\n"); }// main.c #include void func() {printf("公众号\n"); } int main(void) {func();return 0; }编译&#xff1a;$ gcc -o main …