c/c++软件开发的注意事项

15种 C++ 常见报错 阅读详情

c/c++软件开发的注意事项
第一部分软件编程的时间分配概况

   高效率的程序员并不是敲键盘的速度比别人快,而是他有着良好的编程习惯,节省了别人浪费的时间。因此,要想提高自己的编程效率,根本在于怎么少浪费时间。只要能把别人浪费的时间节省下来,你的效率就可以快过别人,甚至数倍于别人。要想节省时间,当然首先需要明白编程中耗费时间的分配情况。

程序员软件开发的几个阶段:

   1、分析设计,

   分析设计的前提是充分理解需求说明文档,然后分析如何实现它们,并形成设计文档。分析设计的目的是明晰软件架构,软件算法和功能的逻辑,得出必要的设计文档,奠定后面编码的基础。合理的设计可以节省后面编码的时间,不合理甚至错误的设计将导致工作的重新开始,没有设计贸然开始编程会导致一些难以预见的逻辑错误。总之,较好的设计事半功倍。

   2、程序编码

   依照语法、设计文档编码。

   3、程序测试

   测试的目的是检测程序有没有问题,一旦发现问题,问题的定位越准,效率就越高。因此,程序中需要输出必要的提示信息。

   4、软件调试

   测试时发现程序有BUG,自然需要调试。显然,遇到的问题越少,调试的时间就越少。没有什么比一次性写好,不用调试更快的方法了。

   时间虽然无法具体分配到各个阶段,但是第一和第二阶段的质量决定了后面两阶段的时间花费,质量越高,测试和调试时间花费越少。反过来,质量越差,测试和调试时间越长。

第二部分 c/c++中常见的错误

   软件编程的过程中,程序员所犯的并不一定是重大错误,反而一些常见的错误屡见不鲜。这些错误严重影响到编程中测试和调试的时间。这一部分总结一下,时时提醒自己,告诫自己避免这些错误。

常见的错误有:

   1、内存泄露

   在c/c++中,内存管理器不会帮助你自动回收不再使用的内存,不管在什么情况下,采取谨慎的态度,杜绝内存泄露的出现,都是上策。尽管一些工具可以帮助我们检查内存泄露问题,但是编程时还是应该仔细一点,尽早排除这类错误,工具只是用作验证的手段。

   2、内存越界访问

1)读越界,即读了不属于自己的数据,如果所读的内存地址是无效的,程度立刻就崩溃了。如果所读内存地址是有效的,虽然读的时候不会出问题,但由于读到的数据是随机的,它会产生不可预料的后果。

2)写越界,也叫缓冲区溢出,所写入的数据对别人来说是随机的,它也会产生不可预料的后果。

内存越界访问造成的后果非常严重,是程序稳定性的致命威胁之一。更麻烦的是,它造成的后果是随机的,表现出来的症状和时机也是随机的,让BUG的现象和本质看似没有什么联系,这给BUG的定位带来极大的困难。一些工具可以够帮助检查内存越界访问的问题,但也不能太依赖于工具。内存越界访问通常是动态出现的,即依赖于测试数据,在极端的情况下才会出现,除非精心设计测试数据,工具也无能为力。工具本身也有一些限制,甚至在一些大型项目中,工具变得完全不可用。比较保险的方法还是在编程是就小心,特别是对于外部传入的参数要仔细检查。

c/c++中,数组中的越界问题尤其常见。例如:

---------------------------------------------------------------------------------------

#include <stdio.h>

#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
char str[10];
int array[10] = {0,1,2,3,4,5,6,7,8,9};

int data = array[10];// read error: array[10]
array[10] = data;

if(argc == 2)
{
strcpy(str, argv[1]);// write error: argv[1]的字符串可能字符个数超过10
}

return 0;
}
----------------------------------------------------------------------------------------

   3、野指针

   野指针是指已经释放了的内存指针。当调用free(p);p本身没有变化,它指向的内存仍然是有效的。释放掉的内存会被内存管理器重新分配,此时,野指针指向的内存已经被赋予新的意义。对野指针指向内存的访问,无论是有意还是无意的,都为此会付出巨大代价,因为它造成的后果,如同越界访问一样是不可预料的。

较好的对策是:释放内存后立即把对应指针置为空值,这是避免野指针常用的方法。这个方法简单有效,只是要注意,当然指针是从函数外层传入的时,在函数内把指针置为空值,对外层的指针没有影响。比如,你在析构函数里把this指针置为空值,没有任何效果,这时应该在函数外层把指针置为空值。

   4、访问空指针

   空指针在C/C++中占有特殊的地址,通常用来判断一个指针的有效性。空指针一般定义为0。现代操作系统都会保留从0开始的一块内存,至于这块内存有多大,视不同的操作系统而定。一旦程序试图访问这块内存,系统就会触发一个异常/信号。

操作系统为什么要保留一块内存,而不是仅仅保留一个字节的内存呢?原因是:一般内存管理都是按页进行管理的,无法单纯保留一个字节,至少要保留一个页面。保留一块内存也有额外的好处,可以检查诸如p==NULL; p[1]之类的内存错误。

在一些嵌入式系统(如arm7)中,从0开始的一块内存是用来安装中断向量的,没有MMU的保护,直接访问这块内存好像不会引发异常。不过这块内存是代码段的,不是程序中有效的变量地址,所以用空指针来判断指针的有效性仍然可行。

   5、引用未初始化的变量

   未初始化变量的内容是随机的(有的编译器会在调试版本中把它们初始化为固定值,如0xcc),使用这些数据会造成不可预料的后果,调试这样的BUG也是非常困难的。

较好的习惯是:在声明变量时就对它进行初始化。另外也要重视编译器的警告信息,发现有引用未初始化的变量,立即修改过来。

   6、指针运算

   依照指针类型进行指针运算,指针偏移值。

   7、结构的成员顺序变化引起的错误

   如:

-------------------------------------------------------------------------------------

Struct s
{
int l;
char* p;
};

int main(int argc, char* argv[])
{
struct s s1 = {4, "abcd"};

return 0;
}

-------------------------------------------------------------------------------------
以上这种方式是非常危险的,原因在于你对结构的内存布局作了假设。如果这个结构是第三方提供的,他很可能调整结构中成员的相对位置。而这样的调整往往不会在文档中说明,你自然很少去关注。如果调整的两个成员具有相同数据类型,编译时不会有任何警告,而程序的逻辑可能相距十万八千里了。

正确的初始化方法应该是(当然,一个成员一个成员的初始化也行):

-------------------------------------------------------------------------------------

struct s
{
int l;
char* p;
};

int main(int argc, char* argv[])
{
struct s s1 = {.l=4, .p = "abcd"};

return 0;
}

-------------------------------------------------------------------------------------

   8、结构的大小变化引发的错误

   我们看看下面这个例子:

-------------------------------------------------------------------------------------

struct base
{
int n;

};

struct s
{
struct base b;
int m;
};

-------------------------------------------------------------------------------------
在OOP中,我们可以认为第二个结构继承了第一结构,这有什么问题吗?当然没有,这是C语言中实现继承的基本手法。

现在假设第一个结构是第三方提供的,第二个结构是你自己的。第三方提供的库是以DLL方式分发的,DLL最大好处在于可以独立替换。但随着软件的进化,问题可能就来了。

当第三方在第一个结构中增加了一个新的成员int k;,编译好后把DLL给你,你直接把它给了客户了,让他们替换掉老版本。程序加载时不会有任何问题,在运行逻辑可能完全改变!原因是两个结构的内存布局重叠了。

解决这类错误的唯一办法就是重新编译全部代码。由此看来,动态库并不见得可以动态替换,如果你想了解更多相关内容,建议你阅读《COM本质论》。

   9、分配/释放不配对

   大家都知道malloc要和free配对使用,new要和delete/delete[]配对使用,重载了类new操作,应该同时重载类的delete/delete[]操作。这些都是书上反复强调过的,除非当时晕了头,一般不会犯这样的低级错误。

而有时候我们却被蒙在鼓里,两个代码看起来都是调用的free函数,实际上却调用了不同的实现。比如在Win32下,调试版与发布版,单线程与多线程是不同的运行时库,不同的运行时库使用的是不同的内存管理器。一不小心链接错了库,那你就麻烦了。程序可能动则崩溃,原因在于在一个内存管理器中分配的内存,在另外一个内存管理器中释放时就会出现问题。

10、返回指向临时变量的指针

   大家都知道,栈里面的变量都是临时的。当前函数执行完成时,相关的临时变量和参数都被清除了。不能把指向这些临时变量的指针返回给调用者,这样的指针指向的数据是随机的,会给程序造成不可预料的后果。

下面是个错误的例子:

-------------------------------------------------------------------------------------
char* get_str(void)
{
char str[] = {"abcd"};

return str;
}

int main(int argc, char* argv[])
{

char* p = get_str();

printf("%s/n", p);

return 0;
}

-------------------------------------------------------------------------------------

下面这个例子没有问题,大家知道为什么吗?

-------------------------------------------------------------------------------------
char* get_str(void)
{
char* str = {"abcd"};

return str;
}

int main(int argc, char* argv[])
{

char* p = get_str();

printf("%s/n", p);

return 0;
}

-------------------------------------------------------------------------------------

   11、试图修改常量

   在函数参数前加上const修饰符,只是给编译器做类型检查用的,编译器禁止修改这样的变量。但这并不是强制的,你完全可以用强制类型转换绕过去,一般也不会出什么错。

而全局常量和字符串,用强制类型转换绕过去,运行时仍然会出错。原因在于它们是放在.rodata里面的,而.rodata内存页面是不能修改的。试图对它们修改,会引发内存错误。

下面这个程序在运行时会出错:

-------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
char* p = "abcd";
*p = '1';

return 0;
}

-------------------------------------------------------------------------------------

12、误解传值与传引用(函数参数单向传值问题)

   在C/C++中,参数默认传递方式是传值的,即在参数入栈时被拷贝一份。在函数里修改这些参数,不会影响外面的调用者。如:

-------------------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>

void get_str(char* p)
{

p = malloc(sizeof("abcd"));

strcpy(p, "abcd");

return;
}

int main(int argc, char* argv[])
{
char* p = NULL;

get_str(p);

printf("p=%p/n", p);

return 0;
}

-------------------------------------------------------------------------------------

在main函数里,p的值仍然是空值。当然在函数里修改指针指向的内容是可以的。

   13、重名符号(变量的作用域问题)

   无论是函数名还是变量名,如果在不同的作用范围内重名,自然没有问题。但如果两个符号的作用域有交集,如全局变量和局部变量,全局变量与全局变量之间,重名的现象一定要坚决避免。gcc有一些隐式规则来决定处理同名变量的方式,编译时可能没有任何警告和错误,但结果通常并非你所期望的。

下面例子编译时就没有警告:

-------------------------------------------------------------------------------------
t.c

#include <stdlib.h>
#include <stdio.h>

int count = 0;

int get_count(void)

{
return count;
}

main.c

#include <stdio.h>

extern int get_count(void);

int count;

int main(int argc, char* argv[])
{
count = 10;

printf("get_count=%d/n", get_count());

return 0;

}

-------------------------------------------------------------------------------------

如果把main.c中的int count;修改为int count = 0;,gcc就会编辑出错,说multiple definition of `count’。它的隐式规则比较奇妙吧,所以还是不要依赖它为好。

   14、栈溢出

   我们在前面关于堆栈的一节讲过,在PC上,普通线程的栈空间也有十几M,通常够用了,定义大一点的临时变量不会有什么问题。

而在一些嵌入式中,线程的栈空间可能只5K大小,甚至小到只有256个字节。在这样的平台中,栈溢出是最常用的错误之一。在编程时应该清楚自己平台的限制,避免栈溢出的可能。

   15、误用sizeof。

   尽管C/C++通常是按值传递参数,而数组则是例外,在传递数组参数时,数组退化为指针(即按引用传递),用sizeof是无法取得数组的大小的。

从下面这个例子可以看出:

-------------------------------------------------------------------------------------

void test(char str[20])
{
printf("%s:size=%d/n", __func__, sizeof(str));
}

int main(int argc, char* argv[])
{
char str[20] = {0};

test(str);

printf("%s:size=%d/n", __func__, sizeof(str));

return 0;
}

[root@localhost mm]# ./t.exe
test:size=4
main:size=20

-------------------------------------------------------------------------------------

     16、字节对齐

   字节对齐主要目的是提高内存访问的效率。但在有的平台(如arm7)上,就不光是效率问题了,如果不对齐,得到的数据是错误的。

所幸的是,大多数情况下,编译会保证全局变量和临时变量按正确的方式对齐。内存管理器会保证动态内存按正确的方式对齐。要注意的是,在不同类型的变量之间转换时要小心,如把char*强制转换为int*时,要格外小心。

另外,字节对齐也会造成结构大小的变化,在程序内部用sizeof来取得结构的大小,这就足够了。若数据要在不同的机器间传递时,在通信协议中要规定对齐的方式,避免对齐方式不一致引发的问题。

   17、大小端问题(字节顺序)

   字节顺序历来是设计跨平台软件时头疼的问题。字节顺序是关于数据在物理内存中的布局的问题,最常见的字节顺序有两种:大端模式与小端模式。

大端模式是高位字节数据存放在低地址处,低位字节数据存放在高地址处。

小端模式指低位字节数据存放在内存低地址处,高位字节数据存放在内存高地址处;

在普通软件中,字节顺序问题并不引人注目。而在开发与网络通信和数据交换有关的软件时,字节顺序问题就要特殊注意了。

   18、多线程共享变量没有用valotile修饰

   关键字valotile的作用是告诉编译器,不要把变量优化到寄存器里。在开发多线程并发的软件时,如果这些线程共享一些全局变量,这些全局变量最好用valotile修饰。这样可以避免因为编译器优化而引起的错误,这样的错误非常难查。

   19、忘记函数的返回值

   函数需要返回值,如果你忘记return语句,它仍然会返回一个值,因为在i386上,EAX用来保存返回值,如果没有明确返回,EAX最后的内容被返回,所以EAX的内容是随机的。

第三部分编写程序和检查程序的良好习惯

   第一阶段分析设计

   充分理解需求,设计软件框架时数据流,控制流尽可能完整;形成尽可能详尽的流程图;涉及到算法类的设计时,要将涉及到的数学公式或思想深入理解,如果需要采用快速算法的,可以参考经典的算法。参考网上的几篇博客和《高质量》

   第二阶段编写代码的习惯

   按照设计文档编,遵照良好的规范书写代码(文献【1】),时时刻刻牢记上面提到的二十种常见错误,争取第一次书写时就避免这样的错误。

   程序完成后,不急着编译,而是先仔细阅读:

1、第一遍阅读:重点关注语法错误、代码排版和命名规则等等问题,只要看不顺眼就修改它们。读完之后,你的代码很少有低级错误,看起来也比较干净清爽。

   2、第二遍阅读:重点关注第二部分的常见编程错误。

   3、模拟计算机执行:常见错误是比较死的东西,按照检查列表一条一条的做就行了。有些逻辑通常不是这么直观的,这时可以自己模拟计算机去执行,假想你自己是计算机,读入这些代码时你会怎么处理。这种方法能有效的完善我们的思路,考虑不同的输入数据,各种边界值,这能帮助我们想到一些没有处理的情况,让程序的逻辑更严谨。

至于读几遍合适,要根据情况而定,通常三遍是最佳的投资。

其他几项良好习惯:
1. 一组良好的接口,实现构造和析构函数。
2. 隐藏内部细节:内部函数尽量使用static声明,最好结构声明都不要放在头文件里,除非确实需要提供给外部。
3. 良好的编程风格:排版,布局,注释,命名需要规范。
4. 尽量满足同时供c/c++调用,条件声明成 extern“c”
---------------------------------------------------------------

#if defined(__cplusplus)
extern "C" {
#endif

#if defined(__cplusplus)
}
#endif

---------------------------------------------------------------
5. 需要带有自动测试程序,Demo程序。
6. 加上#ifndef/#define/#endif:防止重复include相同的头文件

C++常见报错解决总结:从编译到运行的全方位避坑指南 C++ 开发中,从编译错误到运行时崩溃,每一个问题都可能成为调试的噩梦。本文系统梳理了 10 类高频错误,包括段错误、内存泄漏、数组越界、多线程竞争等,通过 真实代码示例 解析根本原因,并提供即用解决方案。针对指针管理、未定义行为等复杂问题,分享 RAII 原则、智能指针 和 静态分析工具(如 Valgrind)的使用技巧。文末推荐了 调试工具链 和 最佳实践,助力开发者从根源规避错误,打造健壮的 C++ 程序。 阅读详情

相关推荐

【log4】c++日志工具之——log4cpp

1、log4cpp概述 Log4cpp是一个开源的C++类库,它提供了C++程序中使用日志和跟踪调试的功能,它的优点如下: 提供应用程序运行上下文,方便跟踪调试; 可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等; 可以动态控制日志记录级别,在效率和功能中进行调整; 所有配置可以通过配置文件进行动态调整; 多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(...

我的笔记本 8053

c++ valotile关键字

对于常量和指针类型如: valotile int a = 0; valotile* char ch = NULL; 作用是告诉编译器,不要对我进行优化,如果涉及到我情况,如读取整型a或者指针ch,需要在我的保存地址中进行存取; 对于多线程情况下,对某些互斥量,如count可能会被两个线程使用,此时 使用valotile int count,可避免读取到错误数据 ...

tianlanl10的博客 917

C/C++编程中容易犯的10种初级编程错误

根据实际工作中碰到的问题,列举出C/C++编程新手容易犯的10种编程错误。

dvlinker的技术专栏 8901

C++编程常见错误及处理

C++编程常见错误及处理。在 C++ 程序错误一般分类:语法错误;运行错误;语义错误(也称逻辑错误)。本文介绍相关错误产生的原因及处理

cnds123的专栏 1万+

C/C++教程目录及说明

C/C++教程专栏目录以及一些说明

余识- 1万+

C/C++ 流程图自动生成器:提升代码理解与协作效率

流程图是一种图形化表示算法、工作流或过程的方法,它使用不同的符号来代表不同类型的动作,例如矩形用于表示处理步骤,菱形用于表示决策点。通过清晰的视觉布局,流程图能够帮助人们理解和分析复杂系统和程序。C语言是一种高级编程语言,以其高效、灵活而广受欢迎。C语言设计简洁,执行效率高,内存管理能力强,支持结构化编程和模块化设计,使其成为系统编程和嵌入式开发的首选语言。它提供了对硬件层的接近直接访问,因此常用于操作系统开发,以及需要与硬件紧密交互的场合。

weixin_35756373的博客 953

C语言编程注意的地方,零基础学习C/C++需要注意的地方

谈及C/C++,功能强大、应用广泛,一旦掌握了后,若是再自学其他语言就显得轻而易举了。那为什么学C/C++的人少呢?很多人认为C/C++虽然博大精深,但也难学。其实就本人认为C/C++并非是“difficult(困难)”的,只要你能理清思路,掌握它的精髓,配合一套教材。那么学C/C++是一件非常容易且又其乐无穷的事。今天本人就与大家一起谈谈如何学习C/C++或者说学习C/C++应从哪几方面着手。先...

weixin_31091881的博客 625

一文读懂无人机AI识别算法,原理、技术、应用

本文详细介绍了无人机识别算法的工作原理、技术优势以及在多个行业的应用前景,展现了其在提升安全监控、资源管理和应急响应中的关键作用。尽管无人机识别算法在多个领域展现出巨大潜力,但仍面临技术挑战,如算法的准确性、数据的实时处理能力以及对复杂环境的适应性。4. 消防与城市管理: 无人机识别算法在消防和城市管理中的应用,为相关部门提供了及时的信息支持,提升了应急处置能力和城市管理水平。1. 公安监控: 无人机识别算法在公安领域的应用,可以实时识别犯罪嫌疑人和违法行为,有效提升城市治安管理的智能化水平。

foiadrone的博客 1847

C/C++注册机制

注册机制在C/C++中是指将函数、类或对象记录到某个全局或局部管理系统中,以便后续能够按需查找和调用。这种机制常用于插件系统、回调管理、对象工厂等场景。

Made In SQL 1137

Hermes+MemOS记忆系统:用SQLite构建可编辑AI个人认知资产

AI记忆不是简单延长上下文或叠加RAG,而是构建具备分层存储、混合检索与自然语言反馈能力的个人认知资产。其核心原理在于将用户交互痕迹(L1)、偏好策略(L2)、结构化世界模型(L3)和结晶化技能统一管理,实现记忆的可追溯、可修正、可进化。技术价值体现在降低token消耗、提升长程一致性、支持离线演进,并突破传统‘静态快照’式知识库局限。典型应用场景包括个人知识助手、客服工单分析Agent、研发文档理解系统等。本文聚焦Hermes Agent与MemOS深度集成方案,详解SQLite作为ACID底座支撑L1/

weixin_33623304的博客 434

信贷审批中的那些坑:从零开始搭建风控策略体系的5个关键步骤

本文深入探讨了信贷审批中的风控策略体系搭建,从数据陷阱识别、规则冲突诊断到反欺诈攻防,提供了5个关键步骤的实战指南。重点解析了如何通过特征工程、决策树优化和模型可解释性技术,构建动态平衡的风控体系,有效降低逾期风险并提升审批效率。

weixin_29253711的博客 412

Borland C/C++ 3.1 完整版(BC3.1)资源下载介绍

Borland C/C++ 3.1 完整版(BC3.1)资源下载介绍 【下载地址】BorlandCC3.1完整版BC3.1资源下载介绍 Borland C/C++ 3.1 完整版(BC3.1)是一款经典的编程工具,专为开发16位程序而设计,尤其适合编译生成uCOS代码。作为一款历史悠久的开发环境,BC3.1在嵌入式系统和...

gitblog_06797的博客 646

BH1750光强度传感器Stm32f103驱动(已测试ok)

1. 实验:Stm32f103 驱动 bh1750采集光照强度,串口打印采集到的数据。 2. 实验准备器材 开发版:stm32f103c8t6 器件:bh1750 GY-302 开发环境:win10,KILE4 下载程序的软件:FlyMcu.exe 串口调试助手:ComAssistant.exe 3. BH1750 的接线 VCC:5V或3.3V ...

weixin_53329977的博客 8928

制作C/C++动态链接库(dll)若干注意事项

制作C/C++动态链接库(dll)若干注意事项 转载于:https://www.cnblogs.com/endenvor/p/9512125.html

weixin_34059951的博客 138

RAG项目简历包装指南:从“流水线工人”到“问题解决者”的跃迁(附代码与思路)

本文代码已在Python 3.11 + CUDA 12.3环境测试,部分功能需LangChain 0.2+支持。

Conan_0728的博客 1885

A Macro- and Micro-Hierarchical Transfer Learning Frameworkfor Cross-Domain Fake News Detection

近年来,社交媒体上假新闻的快速和广泛传播对人们的日常生活构成了越来越大的威胁[6, 14, 19]。为了有效打击假新闻,自动检测假新闻变得至关重要[39]。新闻内容[11, 16, 20, 27]和用户互动(即用户互动)[1, 24, 34]。基于这些类型的数据,提出了单领域假新闻检测,它从新闻文章、用户互动或两者中提取有效特征,以识别单个新闻领域内新闻的真实性(即新闻是真是假)(例如,政治新闻或娱乐新闻)。

qq_52053775的博客 155

如何在VSCode上运行C/C++代码

本文介绍如何在VSCode上运行C/C++代码

诸神缄默不语的博客 1万+

Coze智能体开发:扣子智能体设置多Agent模式

在扣子中创建智能体后,智能体默认使用单 Agent 模式。在单 Agent 模式下处理复杂任务时,你必须编写非常详细和冗长的提示词,而且你可能需要添加各种插件和工作流等,这增加了调试智能体的复杂性。调试时任何一处细节改动,都有可能影响到智能体的整体功能,实际处理用户任务时,处理结果可能与预期效果有较大出入。

王国平的博客 3712

【C/C++】Dev-C++的安装与使用以及快捷键整理

有时候也叫做Dev-Cpp,是一个免费软件,最早是由BloodShed公司开发的,在版本4.9.2之后BloodShed公司停止了开发并且开放了源代码,之后是由Orwell公司接手进行维护,Orwell公司陆续开发了几个版本,到5.11版本之后更新就比较少了,但是后来也有一些其他的开发人员开发维护了一些分支版本,比如Dev-C++ 的魔改——小熊猫C++。的工具,Dev-C++ 仍然是一个不错的选择。:在 "Tools" → "Editor Options" → "Syntax" 中更改编辑器配色方案。

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 5018

实例详解C++程序的五大内存分区

本文详细讲述C++程序在运行时的5大内存分区。 下面使用日常开发中的编程实例,详细介绍一下这5个分区,以便大家能更深刻的理解这5大内存分区。 1、栈内存区 栈内存区是我们用的最多的分区,只要有函数的地方都会使用到这个分区。栈分区是用来存放函数参数及函数局部变量值的内存区,是由编译器在编译时自动分配和释放的。 函数中的参数与函数中的局部变量占用的内存是代码执行到函数(进入函数)是分配的,在............

dvlinker的技术专栏 1万+

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【C/C++】不允许你不知道C/C++可以编写前端,JAVA 面临挑战

C/C++就业竞争力的提升,JAVA面临挑战!属性大集合;没想到吧!C/C++语言还能这么用,Qt 你真的是C/C++用明白了。

就业知识博客 3522

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C/C++跨平台SDK开发的注意事项

分享 C/C++ 跨平台 SDK 开发经验,指出选择 C++ 版本要兼顾编译器与应用场景;源码以 UTF - 8 BOM 格式保存防中文乱码;用宏定义或源码隔离平台差异;接口参数和返回值用标准基本类型;用特定库或封装函数处理文件系统操作。文末还提出跨平台开发待讨论命题 。

阳光日志 1971

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C/C++编译器-Dev-Cpp 5.11安装教程(含资源)

C/C++编译器-Dev-Cpp 5.11安装教程(含资源) 去发现同类优质开源项目:https://gitcode.com/ 简介 本资源文件提供了Dev-Cpp 5.11版本的安装教程及相关资源下载。Dev-Cpp是一款轻量级的C/C++集成开发环境(IDE),适合初学者和专业开发者使用。本教程将指导您如何安装和配置Dev-Cpp 5.11,以便您能够快速开始C/C++编程。 安装步骤 1. ...

gitblog_06552的博客 616

vscode配置c/c++教程

可以直接在Microsoft Store 安装,也可以去官网安装,链接在下面⬇️。

liuyuhan2的博客 5739
上一篇: 十个糟糕的程序员的行为
下一篇: 芳烃装置资料一
PerfectToday
博客等级 码龄18年 46粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值