0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

3个C语言编程易犯的错误

Q4MP_gh_c472c21 来源:嵌入式ARM 2019-12-03 15:47 次阅读


典型错误1:指针指向

上述代码意图比较明显:定义了一个int变量a和指针变量pa,并且把a的地址给了指针pa。接着通过键入给a赋值,但运行结果如下:

其实这个问题是我们学习指针的时候的一个典型错误了,我们知道调用scanf函数给变量赋值时,赋值对象要为地址的形式,通常是加取址符“&”,但是这里采用的是*pa的格式,这里涉及的指针相关知识前面给大家讲过,为了更好地理解本题,就再重复一下: 对于指针来说,有己址、己值、它址、它值等特点,己址就是指针变量本身的地址,己值就是指针变量本身地址所存放的值,也就是我们通常说的指向的地址,这也正是它址,所以己值和它址意义是一样的,而它值就是指针指向地址位置所存放的值。 而这里的*pa表示的意义就是它值a,那就是说这么写的话下面两行代码是等价的:

scanf("%d", *pa);scanf("%d", a);

对比过后显然是错误的,大家一眼看出a要写成&a,这没问题。但也有人说可以把*pa改成&pa,这样行吗?其实这么说的人还是对指针中己值和己址的概念没搞清楚,&pa表示的意义是己址,即指针变量本身的地址,就是说你试图用scanf修改指针变量本身地址上的值,而这个值原本是变量a的地址,其实就是在修改指针的指向!正确的写法应该这样:

scanf("%d",pa);

pa表示a的地址,即为它址,也就是&a,所以上面写法才与下面的等价:

scanf("%d", &a);

典型错误2:getchar函数

char c;while((c=getchar())!=EOF){...}
这段代码的本意是用getchar函数读取缓冲区字符直到结束,但是在编译运行时,发现上面几行代码一直报错!逻辑上没问题啊,那这究竟错在哪里?读者可以自己思考一下再往下看。

其实产生报错的原因有两点,一个是对getchar函数理解不到位,另一个是EOF的问题。
我们首先来说说getchar函数的问题,标准库中给出了该函数的使用说明:在它读取一个字符后,会将其转换为int类型返回,所以首先char c要改为int c,关于getchar的问题还没讲完,后面还要说。 我们接着来看看EOF的问题,初学者对它的理解经常会有偏差,首先它是一个宏,定义于头文件,为-1;其次它并不是很多人理解的文件结束符,实际上它是一个标志位,区别于其他所有字符的存在,表示一种没有其他字符的信号。 讲到这里,我们再回到getchar函数,由上面可以看出它的返回值必须是一个能包含所有字符的数据类型,方便它表示任意字符和EOF等标志位。 因此,上面代码的错误就很明显了,可能有两种情况:1.如果编译器中的char是有符号的且EOF被定义为-1,而恰好有字符等于0xff,那么getchar就会提前结束。当然,如果输入全部是7位以下的字符,那很长时间不会有错误。2.如果编译器中的char是无符号的,则实际的EOF值会被截断,不再会识别为EOF,将会陷入无限循环。

这里肯定会有人问我们键入-1来模拟EOF跳出循环不行吗?实际上是不行的,-1是有-和1两个字符组成的,而getchar一次只能读取一个字符,所以上述代码EOF与从键盘输入的字符无关,那这岂不是只能死循环了?当然不是,我们可以通过按键组合ctrl+d或者ctrl+z来指示结束,当然,这里的按键组合输入只是我们的一种约定,不应该显示检查按键组合的值。

典型错误3:存储机制

char *p = NULL;p = "hello world";strcpy(p, "hello world");
题目很简单,就问这段代码写的有没有问题,如果有,问题在哪里?

其实这个问题如果你对C语言的存储机制非常熟悉的话,应该是很简单的:我们简单分析一下,第一行代码是没问题的,第二行意思是让指针p指向字符串常量,单看也没问题,而问题就出在第三行了,它的意图是对指针p指向地址的内容进行修改,当然还用“hello world”只是为了增加点迷惑性而已。

上面说到了C语言的内存机制,其实第二行代码过后,hello world 作为字符串常量存放于内存中的常量区,且是只读,而此时指针p存放的是字符串常量的地址,第三行代码企图通过strcpy修改只读段的内容,因此很明显会报错,这也是这三行代码的问题所在了。

关于C的存储问题,可能有的人还不太了解,那就借这个机会简单给大家提几句,这也是以前我写过的问题:

一个编译的C程序占用的内存分为以下几个部分:
1、栈区(stack)—也称自动类型存储区,由编译器自动分配释放,存放函数的参数值,局部变量的值等,例如函数调用结束后自动释放。

2、堆区(heap)—也称动态分配内存区,由程序员分配释放,从分配到程序结束为止,若不释放,程序结束时可能由OS回收,比如malloc分配的内存,free释放的内存。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。

4、文字常量区—常量字符串放在这里,程序结束后由系统释放。

5、程序代码区—编译后的程序代码放在这里。 来看一个具体的C程序

怎么样?问题虽然简单,但也给我们以后写代码提了个醒,这种不易察觉的错误大家一定要小心再小心,尽量避免,就说到这里吧,感谢大家耐心阅读!
-END-

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7551

    浏览量

    131919
  • 函数
    +关注

    关注

    3

    文章

    4131

    浏览量

    61553

原文标题:3个C语言编程易犯的错误:也许你也犯过(附代码)

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    PLC的编程方式及编程语言

    在工业自动化领域,PLC(Programmable Logic Controller,可编程逻辑控制器)因其强大的控制功能和灵活的编程方式而得到了广泛应用。PLC的编程方式和编程
    的头像 发表于 06-27 14:08 133次阅读

    PLC编程语言和C语言的区别

    在工业自动化和计算机编程领域中,PLC(可编程逻辑控制器)编程语言和C语言各自扮演着重要的角色。尽管两者都是
    的头像 发表于 06-14 17:11 422次阅读

    C语言中的错误处理机制解析

    C 语言不提供对错误处理的直接支持,但是作为一种系统编程语言,它以返回值的形式允许您访问底层数据。
    的头像 发表于 02-26 11:19 315次阅读

    plc编程语言与c语言的联系 c语言和PLC有什么区别

    PLC编程语言与C语言的联系 PLC(可编程逻辑控制器)是一种针对自动化控制系统的特殊计算机。PLC编程
    的头像 发表于 02-05 14:21 2071次阅读

    汽车ECU编程是单片机C语言还是汇编语言

    汽车ECU编程是单片机C语言吗?还是汇编语言
    发表于 01-26 06:08

    invalid synrax是什么错误

    “invalid synrax” 是英语中的拼写错误,正确的拼法是 “invalid syntax”。语法错误是指程序代码中出现了不符合编程语言规则的语法结构,导致编译器无法理解和编译
    的头像 发表于 11-28 15:59 5841次阅读

    c语言代码错误怎么找

    当我们编写C语言代码时,常常会遇到一些错误。这些错误可能是语法错误,逻辑错误或者是运行时错误。无
    的头像 发表于 11-24 10:05 1854次阅读

    脚本语言编程语言的区别

    脚本语言编程语言是计算机语言的两个主要分类。尽管两者都是用于编写计算机程序的工具,但它们在设计和运行方式上存在一些显著的区别。下面将详细探讨脚本
    的头像 发表于 11-22 14:33 1985次阅读

    如何持续的提高C语言编程能力?

    想持续提高C语言编程能力,该怎么做。 现在是简单的程序可以写,指针用的很少,指来指去的,编译了全都是错。
    发表于 09-28 08:31

    Linux下C语言编程入门教程

    编程风格等。u3000u3000Linux 作为一优秀的操作系统,一项非常重要的功能就是支持系统调用尤其是支持C语言的系统调用功能十分的方便、快捷。
    发表于 09-22 06:56

    STM8 C语言精品编程100例

    本文档的主要内容详细介绍的是STM8C语言精品编程100例的PDF电子书免费下载。实例说明本例要实现三LED同时闪烁,实现1秒钟闪亮,1秒钟熄灭。在剑齿虎开发版上集成了
    发表于 09-21 07:01

    Rust语言错误处理的机制

    在Rust语言中,错误处理是一项非常重要的任务。由于Rust语言采用静态类型检查,在编译时就能发现很多潜在的错误,这使得程序员能够更加自信和高效地开发程序。然而,即使我们在编译时尽可能
    的头像 发表于 09-19 14:54 914次阅读

    五种支持plc编程语言有哪些

    在PLC控制系统设计中,不同型号的PLC编程软件对以上五种编程语言的支持种类是不同的,所以不但对PLC的硬件性能了解外,也要了解PLC对编程语言
    发表于 08-31 14:54 797次阅读
    五种支持plc<b class='flag-5'>编程</b>的<b class='flag-5'>语言</b>有哪些

    嵌入式系统C语言编程中主要的错误处理方式

    本文主要总结嵌入式系统C语言编程中,主要的错误处理方式。
    发表于 07-24 16:40 641次阅读
    嵌入式系统C<b class='flag-5'>语言</b><b class='flag-5'>编程</b>中主要的<b class='flag-5'>错误</b>处理方式

    PLC编程语言的特点

    PLC的编程语言与一般计算机语言相比,具有明显的特点,它既不同于高级语言,也不同与一般的汇编语言,它既要满足易于编写,又要满足易于调试的要求
    的头像 发表于 07-04 17:13 699次阅读