目录

  • 1 第一章 C语言简介
    • 1.1 C语言前世今生
    • 1.2 主流开发环境介绍
    • 1.3 第一个小程序解析
    • 1.4 常见编译错误
    • 1.5 章节知识点小结
  • 2 算法基础
    • 2.1 算法-程序的灵魂
    • 2.2 算法的描述-流程图
  • 3 数据类型与运算符
    • 3.1 数据描述
    • 3.2 运算符和表达式1
    • 3.3 运算符和表达式2
    • 3.4 章节知识点小结
  • 4 顺序结构程序设计
    • 4.1 输入和输出
    • 4.2 顺序结构程序设计
    • 4.3 章节知识点小结
  • 5 选择结构程序设计
    • 5.1 关系运算符和关系表达式
    • 5.2 逻辑运算符和逻辑表达式
    • 5.3 if语句
    • 5.4 条件运算符
    • 5.5 switch语句
    • 5.6 章节知识点小结
  • 6 循环结构程序设计
    • 6.1 while循环结构
    • 6.2 do_while循环结构
    • 6.3 for循环结构
    • 6.4 循环的嵌套
    • 6.5 break语句和continue语句
    • 6.6 章节知识点小结
  • 7 数组
    • 7.1 一维数组
    • 7.2 二维数组
    • 7.3 字符数组
    • 7.4 章节知识点小结
  • 8 函数
    • 8.1 子程序设计
    • 8.2 函数定义
    • 8.3 函数的调用
    • 8.4 局部变量和全局变量
    • 8.5 参数传递
    • 8.6 函数递归调用
    • 8.7 章节知识点小结
  • 9 指针
    • 9.1 指针的基本概念
    • 9.2 指针变量的定义及引用
    • 9.3 通过指针引用数组元素
    • 9.4 指向多维数组的指针和指针变量
    • 9.5 用指向数组的指针作函数参数
    • 9.6 指针与字符串
    • 9.7 函数指针和指针函数
    • 9.8 章节知识点小结
  • 10 用户自己建立数据类型
    • 10.1 定义和使用结构体变量
    • 10.2 使用结构体数组
    • 10.3 结构体指针
    • 10.4 章节知识点小结
  • 11 编译预处理
    • 11.1 宏定义预处理
    • 11.2 文件包含预处理
    • 11.3 条件编译预处理
    • 11.4 章节知识点小结
  • 12 文件
    • 12.1 文件的基本知识
    • 12.2 文件的基本操作
    • 12.3 章节知识点小结
常见编译错误


一、常见错误分析

1.编译错误

1error C2001: newline in constant

编号:C2001 

直译:在常量中出现了换行。

错误分析:

字符串常量、字符常量中是否有换行。

在这句语句中,某个字符串常量的尾部是否漏掉了双引号。

在这语句中,某个字符串常量中是否出现了双引号字符"”,但是没有使用转义符  \"”。

在这句语句中,某个字符常量的尾部是否漏掉了单引号。

是否在某句语句的尾部,或语句的中间误输入了一个单引号或双引号。

2error C2015: too many characters inconstant

编号:C2015 

直译:字符常量中的字符太多了。

错误分析:

单引号表示字符型常量。一般的,单引号中有且只能有一个字符,如果单引号中的字符数多于 4 个,就会引发这个错误;如果单引号中的字符数是 2­个,编译不报错,输出结果是这几个字母的 ASC 码作为一个整数(int4B)整体看待的数字。

如果语句中某个字符常量缺少右边的单引号,也会引发这个错误,例如: 

if (x == 'x || x == 'y') { … } 

两个单引号之间不加任何内容会引发如下错误:error C2137: empty character constant

3error C2018: unknown character'0x##'

编号:C2018 

直译:未知字符‘0x##’。

错误分析: 

0x##是字符 ASC 码的 16 进制表示法。这里说的未知字符,通常是指全角符号、字母、数字,或者直接输入了汉字。如果全角字符和汉字用双引号包含起来,则成为字符串常量的一部分,是不会引发这个错误的。

4error C2065: 'xxxx' : undeclaredidentifier

编号:C2065 

直译:标识符“xxxx”未定义。

错误分析:

标志符是程序中出现的除关键字之外的词,通常由字母、数字和下划线组成,不能以数字开头,不能与关键字重复,并且区分大小写。变量名、函数名、类名、常量名等都是标志符。所有的标志符都必须先定义,后使用。标志符有很多种用途,所以错误也有很多种原因。

如果“xxxx”是一个变量名,那么通常是程序员忘记了定义这个变量,或者拼写错误、大小写错误所引起的,所以,首先检查变量名是否正确。

如果“xxxx”是一个函数名,那就怀疑函数名是否没有定义。可能是拼写错误或大小写错误,也有可能是你所调用的函数根本不存在。还有一种可能,你写的函数在你调用所在的函数之后,而你有没有在调用之前对函数原形进行申明。

如果“xxxx”是一个库函数的函数名,那么看看是否包含了这些库函数所在的头文件(.h文件)例如,使用“sqrt”函数需要头文件 math.h

前面某句语句的错误也可能导致编译器误认为这一句有错。如果你前面的变量定义语句有错误,编译器在后面的编译中会认为该变量从来没有定义过,以致后面所有使用这个变量的语句都报这个错误。如果函数申明语句有错误,那么将会引发同样的问题。

5error C2086: 'xxxx' : redefinition

编号:C2086

直译:xxxx”重复申明。

错误分析:

变量“xxxx”在同一作用域中定义了多次。检查“xxxx”的每一次定义,只保留一个,或者更改变量名。

6error C2146: syntax error : missing';' before (identifier) 'xxxx'

编号:C21436

直译:在(标志符)  xxxx”前缺少分号。

错误分析:

当出现这个错误时,往往所指的语句并没有错误,而是它的上一句语句发生了错误。上一句语句的很多种错误都会导致编译器报出这个错误:

1上一句语句的末尾真的缺少分号,补上就可以了。

2上一句语句不完整,或者有明显的语法错误,或者根本不能算上一句语句。

2.链接错误

1error LNK2001: unresolved externalsymbol _main

编号:LNK2001 

直译:未解决的外部符号:_main

错误分析:缺少 main函数。看看 main的拼写或大小写是否正确。

2error LNK2005: _main alreadydefined in xxxx.obj

编号:LNK2005 

直译:_main已经存在于 xxxx.obj 中了。

错误分析:

直接的原因是该程序中有多个(不止一个)main 函数。这是初学C的同学在初次上机编程时经常犯的错误。这个错误通常不是你在同一个文件中包含有两个  main 函数,而是在一个project(项目)中包含了多个C文件,而每个 C文件中都有一个 main函数。引发这个错误的过程一般是这样的:当写完成了一个 C程序的调试,接着准备写第二个 C文件,你可能通过右上角的关闭按钮关闭了当前的C文件子窗口(或者没有关闭),然后通过菜单或工具栏创建了一个新的C文件,在这个新窗口中,程序编写完成,编译,然后就发生了以上的错误。原因是这样的:在创建第二个 C文件时,没有关闭原来的项目,所以无意中将新的 C文件加入上一个程序所在的项目。切换到“File View”视图,可以发现有两个文件。如图3-1所示。

当完成一个程序以后,写另一个程序之前,一定要在“File”菜单中选择“Close Workspace项,将前一个项目完全关闭,才能进行下一个项目。

二、程序调试 

程序调试是指对程序的查错和排错。当程序编译出错或者链接出错时,会在输出窗口内列出出错信息。如果是编译错误,输出窗口中会列出错误所在文件和出错的行数。只要双击出错信息,就可以自动跳到出错的程序行,并在出错行上设置一个小标志。应当注意的是:有时提示的出错行并不是真正出错的行,如果在提示出错的行上找不到错误的话,可以到一行再找。另外,有时提示出错的类型并非绝对准确,由于出错的情况繁多而且多种错误互有关联,因此要善于分析,找出真正的错误,而不要只从字面意义上死抠出错信息,钻牛角尖。

如果系统提示的出错信息很多,应当从上到下逐一改正,有时显示出一大片出错信息往往使人感到问题严重,无从下手,其实可能是一两个错误。例如,对所用的变量未定义,编译时就会对所有含该变量的语句发出出错信息,只要加上一个变量定义,所有错误就都消除了。

当程序编译成功,需要查看程序执行过程以及其变量值的情况,需要启动调试。

1.程序执行到中途暂停以便观察阶段性结果

方法如下:

1)在需暂停的行上单击鼠标,定位光标;

2)单击菜单“编译”->“开始调试”->Run  to Cursor”,或按【Ctrl+F10】,如图3-2所示,程序执行到光标所在行会暂停。如果把光标移动到后面的某个位置,再按【Ctrl+F10】,程序将从当前的暂停点继续执行到新的光标位置,第二次暂停。


2.设置需观察的结果变量

按照上面的操作,使程序执行到指定位置时暂停,目的是为了查看有关的中间结果。在如3-3,左下角窗口中系统自动显示了有关变量的值,其中的值程序运行时用户输入的,而变量isum 的值是一个随机值,因为他们还未被赋值。图中左侧的箭头表示当前程序暂停的位置。如果还想增加观察变量,可在图中右下角的“Name”框中填入相应变量名。


3.单步执行

当程序执行到某个位置时发现结果已经不正确了,说明在此之前肯定有错误存在。如果能确定一小段程序可能有错,先按上面步骤暂停在该小段程序的第一行,再输入若干个查看变量,然后单步执行,即一次执行一行语句,逐行检查下来,看看到底是哪一行造成结果出现错误,从而能确定错误的语句并予以纠正。

单步执行按“Debug”菜单中的“Step Over”子菜单或按【F10】。如果遇到自定义函数调用, 想进入函数进行单步执行,可执行Step Into”子菜单或按【F11】。当想结束函数的单步执行,可按 Step Out”子菜单或按【Shift+F11】。对不是函数调用的语句来说,【F11】与【F10】作用相同。但一般对系统函数不要使用【F11】。

4.断点的使用

使用断点也可以使程序暂停。设置断点方法如下:

①在需设置断点的行上单击鼠标,定位光标;

②按“编译微型条”中最右面的按钮,如3-3所示,或按【F9】。该操作是一个开关,按一次是设置断点,按二次是取消断点。被设置了断点的行前面会有一个红色圆点标志,如图3-4所示。


3)单击菜单“编译”->“开始调试”->“去”,或按【F5】,如图3-5所示,程序执行到光标所在行会暂停。然后也可通过上面的方法查看相关变量的值。

断点通常用于调试较长的程序,可以避免使用“Run  to  Cursor”功能时,经常要把光标定位到不同的地方。而对于长度为上百行的程序,要寻找某位置并不太方便。如果一个程序设置了多个断点,按一次【F5】会暂停在第一个断点,再按一次【F5】会继续执行到第二个断点暂停,依次执行下去。

5. 停止调试

使用“Debug”菜单的“Stop Debugging”菜单项,或【Shift+F5】键可以结束调试,从而回到正常的运行状态。