C++程序常见错误总结

在 C++ 程序设计中,有以下 3 类错误:

  1. 语法错误;
  2. 运行错误;
  3. 语义错误;

我们结合具体案例,来讨论这三种错误。

1. 语法错误

语法错误又分为两类: 编译错误 (Compile error),连接错误 (link error).

前者是编译过程中发生的错误,导致无法生成目标文件,

可能的原因有:分号遗漏或多余,括号不匹配,标识符未定义,访问类的 private 成员等。

后者是生成目标文件后,连接过程中发生错误,是针对有多个源文件的情况,

可能的原因有:全局变量重复定义,函数名冲突等。

根据报错的信息,我们修改代码,再次编译和连接,直到没有语法错误为止。

例如,我们有如下代码段:

#include <stdio.h>

class Cat {
    // ...
}

int main() {
	cat* pCat = new cat;
	delete pCat;
	return scanf("%*s");
}

编译会提示,未定义标识符 cat,因为,C++ 严格区分大小写,cat 应该写成 Cat。

另一个案例:

#include <stdio.h>

int main() {
	int a = 3;
	double b = 2:
	printf("%d\n", a % b);
	return scanf("%*s");
}

取模运算,只适用于整型数据,而我们对浮点数 b 取摸,因此会报错。

有时候,我们遇到的只是 Warning ,可以生成目标文件,但为了保险,我们还是应该修改代码,尽量达到 0 error, 0 warning。

2. 运行错误 (Runtime error)

运行过程中,程序可能出现错误。这些错误属于运行错误,不会在编译过程中显现。

例如,我们有以下代码:

#include <stdio.h>

int main() {
	int a = 1;
	int b = 1;
	scanf("%d %d", &a, &b);
	printf("%d\n", a / b);
	return scanf("%*s");
}

如果在运行过程中,输入的第 2 个数为0,则会引发除数为0的异常。

我们可以在做除法前,判断除数是否为 0,从而避免这种异常。

或者使用 try-catch 语句,来处理可能发生的异常。

#include <stdio.h>

int main() {
	int a = 1;
	int b = 1;
	scanf("%d %d", &a, &b);
	try {
		printf("%d\n", a / b);
	}
	catch (...) {
		printf("Runtime error!\n");
		scanf("%*s");
		return 1;
	}
	return scanf("%*s");
}

引发运行错误的原因,不仅有除数为0,还有下标越界,栈溢出等。

下面这段代码, 大家不要轻易运行!

#include <stdio.h>

int main() {
	int* p = NULL;
	while (true) {
		p = new int[1024];
	}
	return scanf("%*s");
}

它可以通过编译,但运行时会无限开辟内存,导致内存耗尽,发生严重错误。

我在 x64 Win10 系统中运行,约 80s 后出现黑屏,系统无响应的情况。

如果增加 try-catch 机制,则可以及时结束这种局面:

#include <stdio.h>

int main(int argc, char** argv) {
	int* p = 0;
	try {
		while (true) {
			p = new int[1024];
		}
	}
	catch (...) {
		printf("Runtime error!\n");
		scanf("%*s");
		return 1;
	}
	return scanf("%*s");
}

3. 语义错误

这种情况,编译没有报错,运行也没有抛出异常,但是输出的结果不正确。

我们看这个案例:

#include <stdio.h>
#define LEN 8

int main() {
    int i = 0;
    int* ar = new int[LEN];
    for (i = 0; i > LEN; ++i) {
        if (1 > scanf("%d", ar + i)) {
            scanf("%*s");
        }
    }
    while (--i >= 0) {
        printf("%d,", ar[i]);
    }
    delete[] ar;
    return scanf("%*s");
}

第 7 行的 i > LEN 应改为 i < LEN,否则程序不会进入循环,不输出任何内容。

我们再看另一个案例:

#include <stdio.h>

class Date {
private:
    int year;
    int month;
    int day;
public:
    Date(int y, int m, int d) {
        year = y;
        m = month;
        day = d;
    }
    // Other functions...
}

int main() {
    Date* date = new Date(2001, 6, 10);
    // ...
    delete date;
    return scanf("%*s");
}

在 Date 的构造函数里,m = month 应改为 month = m;

否则将导致 month 成员没有被初始化,运行结果错误。

如果用严格检查的编译软件,例如 VS 2019,它会在编译时给出 warning,说 month未初始化,从而提示我们,这里可能有错误。

不过,有些语义错误,并不引发 warning ,只在运行过程中表现,很难被察觉。

想要避免这些语义错误,我们就必须认真分析代码。

之后我会总结更多案例。^_^

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《C程序设计谭浩强PDF》是一份非常经典的教材,在众多编程教材中占据重要的地位。本书系统地介绍了C语言的基本语法、程序结构和函数的使用方法,从而帮助读者全面地理解C语言编程的思想和方法。 本书的特点在于,它深入浅出地讲解了C语言的各个方面,不仅涉及到语法知识,还强调了程序设计的思想和方法,同时给出了大量的实例和练习题,帮助读者加深了对C语言的理解和掌握。 《C程序设计谭浩强PDF》整体分为13章,内容包括数据类型、程序流程控制、数组、指针、函数、结构体、文件操作等方面,在讲解完基础知识的同时,还涉及了一些高级的内容,如动态内存分配、位运算、多文件编程等,非常适合初学者和已有一定经验的程序员使用。 总的来说,《C程序设计谭浩强PDF》是一份很不错的C语言学习教材,它不仅适合初学者入门,而且对于有一定编程经验的程序员来说也是一份很好的参考教材。它准确、简明地讲解了C语言的基础知识和高级内容,并给出了大量实例和练习题,在学习中起到了很好的辅助作用。 ### 回答2: 《C程序设计》是由谭浩强编写的一本经典的计算机教材,主要介绍C语言的基本概念、语法特点、程序设计技巧以及实际应用。这本教材的优点在于循序渐进、深入浅出、通俗易懂,非常适合初学者使用。除了基础内容,书中还介绍了一些高级主题,如内存分配、指针运算等,对于C语言的深入实践有很大帮助。 书中案例丰富,代码清晰,通过代码实践,可以更好地理解程序设计的过程和方法。此外,本书还提供了许多习题,可以帮助读者巩固所学知识,提高编程能力。 总的来说,这本书是一本很好的C语言入门教材,具有深入浅出、实用性强等特点,非常适合广大初学者使用,同时也是一本非常经典的计算机教材。 ### 回答3: 《C程序设计》是一本由谭浩强编写的经典教材,对于学习C语言的人来说,是一本必不可少的指导书。书中详细介绍了C语言的基本语法、流程控制、数组、函数等内容,逐步引导读者进入编程的世界。 这本书具有思路清晰、语言简明易懂、内容全面的特点。对于初学者来说,可以通过阅读本书逐步熟悉C语言的用法,并逐步掌握其编程思想,逐渐提升自己的编程能力。对于有一定编程经验的人来说,也可以通过阅读本书来深入理解C语言的特性和内在机制,提高编程水平。 不仅如此,本书还提供了大量的实例和习题,可以帮助读者加深对于各种知识点的理解,并锻炼自己的编程技能。同时,本书还对常见的编程错误和常识进行了归纳和总结,对于提升程序健壮性和正确性也有一定的帮助。 总而言之,谭浩强编写的《C程序设计》是一本不可多得的经典教材,它对于学习C语言以及提高编程水平都有着极大的帮助。通过阅读本书,人们可以在编程的道路上不断前进,成为一名技术精湛的程序员。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值