VS很强大,从经典的VC++ 6.0到VS2013、2015,甚至最新的VS 2019,功能越来越强大,使用越来越方便。但是,对于初学者却显得越来越不友好。
其实初学者使用VS时,不少问题往往只需要根据报错信息,搜索以下,就可以直接解决,今天我们就总结下VS编程中常见的报错信息及解决方案。
有正在学习C语言的朋友,可以进Q群121811911下载软件资料和视频,我们一起进步。
未声明的标识符
error C2065: “cout”: 未声明的标识符
遇到这种情况,网上翻了好多,都是在说是由于缺失#include<iostream>和using namespace std;这两句导致的,但我明明这两句都有了,还是报错。最后发现,居然是预编译头,也就是#include"stdafx.h"必须放在第一行。
类型转换错误
*error C2440: “=”: 无法从“char ”转换为“int”
使用了不安全的函数
error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
C语言的标准函数中,一些读取或写入内存的函数存在内存越界的问题,从而使得内存数据变得不安全。如scanf、gets、strcat等函数都存在着这样的问题。
为了避免这个问题,在VS2015中,另外提供了如scanf_s,get_s,strcat_s等相关的改进函数,来替代原来的标准函数的功能,并通过添加内存读取范围的限制来解决不安全的问题。
在实际的应用中,也许使用VS2015提供的安全函数会更加合理。但是,在学习中,几乎所有的课本以及教程都使用的原来的标准函数,另外考虑到移植性的问题,除了VS2015环境,其他环境中并没有提供改进后的函数。因此,我们通常任然需要标准的库函数来实现相关功能。
但是,如果在VS2015中使用原始的函数,编译器将会报错。这对使用和学习都带来了相当的不变。
左操作数必须为左值
error C2106: “=”: 左操作数必须为左值
表达式由一个或多个操作数通过操作符组合而成。最简单的表达式仅包含一个字面值常量或变量。较复杂的表达式则由操作符以及一个或多个操作数构成。
不严谨的说法是,左值右值的区分在于位于等号的那一侧,左侧的是左值,通常是一个变量,右侧的是右值,可以是一个变量,或者是一个表达式。左值在编译时可知,左值表示存储结果的地方,所以简单理解,左值就是必须有存储结果的地方,有内存空间;至于C++可以运行成功是因为C++编译器已经优化过,表达事返回的并不是a的内容(b的内容) ,而是一个变量 。
需要我们对VS的项目属性进行设置,具体步骤如下。
在项目属性设置中找到选项卡配置属性→C/C++→预处理器;
在右侧的参数中找到预处理器定义,编辑其参数;
在参数的末尾添加定义_CRT_SECURE_NO_WARNINGS
栈崩溃
Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted.
主要问题是数组越界了,你定义了一个字符数组s,大小是2,然后试图给它赋值字符c和一个数字,而字符加一个数字已经是2了,每个字符串末尾应该有个空字符的,但是放不下了,于是编译器很生气,就挂了,还有是变量s冲突,不是变量a冲突,而且你代码中也没有a这个变量。改为char s[3]或者大于三都可以。
堆破坏
HEAP CORRUPTIONG DETECTED
这个错误的原因是,释放一个字符串指针,但是这个字符串指针被破坏了,举例说明:
char *str=(char *)malloc(sizeof(char)*10);//分配了10个字节大小的内存空间
strcpy(str,"1234567890");//字符串拷贝,字符串”1234567890“是11个字符,这个拷贝操作会破坏字符指针str,此时会拷贝11字节到str指向的内存空间里,超过了原来分配的10个字节大小的内存空间
如果这时候用free(str);释放内存就会报错 ---HEAP CORRUPTION DETECTED
函数重复定义
*error C2084: 函数“char GetMyString(int,int)”已有主体
这是由于函数实现了两次引起的,双击出错的代码行自动定位到源代码中,删除重复的源代码。边删除边编译检测还有没有重复实现的函数。删除完所有重复定义的函数后再次编译即可避免此类错误。
函数链接错误
LINK : fatal error LNK1104: 无法打开文件“opencv-user.lib”
或者
error LNK2019: 无法解析的外部符号 "void __cdecl test(void)" (?test@@YAXXZ),该符号在函数 _main 中被引用
遇到这种问题一般都是由于缺少相应的库文件;右击项目,选择“属性”--“链接器”--“输入”--“附加依赖项”
根据错误中的提示在下图右边的红色框内添加相应的lib文件。
预编译头问题
fatal error C1853: “Debug\NR302.pch”预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
该错误是因为当项目中混合了 .cpp 和 .c 文件时,编译器会对它们采取不同的编译方式(主要是因为对函数声明的处理方式不同),因而不能共用一个预编译头文件。在 VC++ 中,默认的预编译头文件是针对 C++ 的 (stdafx.h 和 stdafx.cpp),当然也可以创建针对 C 的预编译头。
方法:将少数的不同类文件设为不使用预编译头是比较平衡的做法,方法是:对于 VC++6.0,在 FileView 里对要取消预编译头的 .c (或 .cpp) 文件点右键,选择 settings,在弹出的对话框右边选择 category 为 precompiled headers,再设置选项为 not using ...;(对于 VS2005,则在 solution explorer 中对相应文件点右键选择 properties,在 precompiled headers 项下设置 not using... 即可。如果需要设置多个文件,则可以按住 Ctrl 键再同时选中这些文件并设置)PS:解释如下点击项目 点击属性 然后选择C/C++ 预编译头 创建使用头文件 不使用预编译头文件(解决方案资源管理器-右击需要排除的c或cpp文件]-弹出属性菜单-展开C/C++-预编译头-创建/使用预编译头-选择不适用预编译头)
大部分是自己学习遇到的问题,有些答案收集自网络,我也刚起步。有正在学习C语言的朋友,可以进Q群121811911下载软件资料和视频,我们一起进步吧。