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

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

3天内不再提示

C语言的经常出现的一些误用和知识总结

信盈达123 来源:CSDN技术社区 作者:叶子一哥 2021-04-15 09:49 次阅读

在学习单片机的时候才真正知道C语言是什么它是来干什么的~但是C语言用到嵌入式只是它小小的一部分他的应用还有很多地方呢,呵呵我们这里就不讨论这个了。我们是不是在写程序的时候错误很多就算编译通过了也达不到我们预期的结果,完了自己是不是也很难找到错在哪儿吧?我绝得语言之所以能称之为语言,它肯定是一种工具一种相互交流相互通信相互传达之间的意图的工具。

作为语言那肯定得有自己的语法,要想相互交流肯定得先学好它的语法吧(比如像表达式,函数,循环,指针)我称之为C语言的语法。C语言虽然很强大但是他也有不少陷阱,所以我发这篇博客有两个目的一是:把C语言一些误用易错的地方总结一下,二是把C语言一些基本语法总结一下~

第一次:

1.关于自增自减(即++i,i++)

要想给一个数加一或减一我们可以:

i += 1;

j -= 1;

而C语言还允许用++和--运算符,其实这里有误导,因为++和--可以作为前缀和后缀,这样的话他们就有可能改变操作数的值,下面让我们来看看:

i = 1;

printf("i is %d\n",++i); /* prints i is 2 */

printf("i is %d\n",i); /* prints i is 2 */

计算表达式i++的结果是i,但是会引发i随后进行自增:

i = 1;

printf("i is %d\n",i++); /* prints i is 1/ */

printf("i is %d\n",i); /* prints i is 2 */

第一个printf 显示了i自增前的原始值,第二个printf显示了i变化后的新值;当然 -- 类似我就不举例了~

但在同一个表达式中多次使用++和--往往很难理解我们看看下面的例子:

i = 1;

j = 2;

k = ++i + j++;

i,j,k最终值分别是2,3,4而++i是2 j++是2;

总结:不管是++i还是i++执行这条语句后i的值都加一了只是(++i)的值加一了而(i++)没变,

2.typedef与#define

2.1.typedef

C语言除了直接使用标准的类型名(如 int char float double)和自己声明的结构体、共用体、指针、枚举类型外,还可以用typedef声明新的类型名来代替现有的类型名。

typedef unsigned char u8;

typedef unsigned int u16;

u8 count;

u16 time;

typedef struct

{

u8 month;

u8 day;

u16 year;

}DATE;

DATE brithday;

总结一下,声明新的类型名的方法:

1.先按定义变量的方法写出定义体(如 unsigned int i)

2.在变量名换成新的变量名(如将 i换成u16)

3.在最前面加上typedef (typedef unsigned int u16)

4.然后用新类型名去定义变量

2.2 #define

2.1.1不带参数的宏定义

#define 标识符 字符串

#define PI 3.1415926

注意:

1.它的作用是在本程序中用指定的标识符PI来代替3.1415926

2.宏定义是用宏来代替字符串也就是做简单的置换,不做正确性检查如果写成

#define PI 3.l4l6926

即把1写成了字母l但是预处理照常代入不做任何语法检查!!

2.1.2带参数的宏定义

#define 宏名(参数) 字符串

#define S(a,b) a*b

area = S(a,b);

#define MAX(x,y) (x)>(y) ? (x):(y)

3.typedef和#define的区别

一般来说typedef 因为它能正确处理指针类型

typedef char *String1;

#define String2 char *

String1 s1,s2;

String2 s3,s4;

s1,s2,s3 被定义为了char* 但s4却被定义为了char型

3.1 static 变量

static变量大致分为三种用法

1. 用于局部变量中,成为静态局部变量. 静态局部变量有两个用法,记忆功能和全局生存期.

2. 用于全局变量,主要作用是限制此全局变量被其他的文件调用.

3. 用于类中的成员.表示这个成员是属于这个类但是不属于类中任意特定对象

1. 静态局部变量

静态局部变量属于静态存储方式,它具有以下特点:

(1)静态局部变量在函数内定义 它的生存期为整个源程序,但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

(2)允许对构造类静态局部量赋初值 例如数组,若未赋以初值,则由系统自动赋以0值。

(3) 对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。

举例如下:

void fun()

{

static int a = 1;

a++;

}

在第一次进入这个函数的时候,变量a被初始化为1!并接着自增1,以后每次进入该函数,a就不会被再次初始化了,仅进行自增1的操作;在static发明前,要达到同样的功能,则只能使用全局变量:

int a = 1;

void fun()

{

a++;

}

2.静态全局变量

全局变量(外部变量)的之前再加上static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于,非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。

由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。

3.static的类成员变量

static关键字有两种意思,你看上下文来判断

1.表示变量是静态存储变量,表示变量存放在静态存储区.

2.表示该变量是内部连接(这种情况是指该变量不在任何{}之内,就象全局变量那样,这时候加上static),也就是说在其它的.cpp文件中,该变量是不可见的(你不能用).

二、static 函数 —— 内部函数和外部函数

当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。

1 内部函数(又称静态函数)

如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数称为内部函数。

定义一个内部函数,只需在函数类型前再加一个“static”关键字即可,如下所示:

static 函数类型 函数名(函数参数表)

{……}

关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。

使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。

2 外部函数

外部函数的定义:在定义函数时,如果没有加关键字“static”,或冠以关键字“extern”,表示此函数是外部函数:

[extern] 函数类型 函数名(函数参数表)

{……}

调用外部函数时,需要对其进行说明:

[extern] 函数类型 函数名(参数类型表)[,函数名2(参数类型表2)……];

编辑:jq

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

    关注

    180

    文章

    7604

    浏览量

    136820
  • 函数
    +关注

    关注

    3

    文章

    4331

    浏览量

    62616
  • 指针
    +关注

    关注

    1

    文章

    480

    浏览量

    70562
收藏 人收藏

    评论

    相关推荐

    使用ADUM4121ARIZ输出15V电压驱动mos/IGBT时,经常出现10ohm电阻损坏的情况,为什么?

    我在使用ADUM4121ARIZ输出15V电压驱动mos/IGBT时,经常出现10ohm电阻损坏的情况,ADUM4121ARIZ的5/6/7/8脚短路。其中10Ohm电阻的右端有根1米的线缆连接
    发表于 12-19 08:07

    ADS1299利用信号发生器发出的正弦信号读到的数据经常出现毛刺,怎么解决?

    近期在做ADS1299的开发,利用信号发生器发出的正弦信号读到的数据经常出现毛刺,调整了SPI的波特率与ADS1299的采样率都没有消除毛刺。毛刺的值也不是0,而是很小的,偏离正常曲线的个值,波形如附图所示,已经测试官方的开发板与自己做的电路板都
    发表于 12-06 06:52

    用tas5630驱动容性负载,经常出现损坏芯片的现象,怎么解决?

    现在我用tas5630驱动容性负载,但是发现经常出现损坏芯片的现象。并不是说工作了很长时间芯片损坏了,而是在有些频率点,上电就坏掉了。这是为什么,有什么好的解决办法吗?谢谢
    发表于 11-07 06:33

    tvp5150am1 RST脚经常出现复位不正常,为什么?

    最近设计的块电路板,TVP5150频繁出现问题,具体原因还没查到,现象总结在这里,希望大家帮忙分析下 1、RST脚经常出现复位不正常,电压值在1.2----3.3V之间。 2、sc
    发表于 09-12 06:23

    使用OPA129构建了个电荷放大器,6脚输出经常出现尖峰的原因?

    使用OPA129构建了个电荷放大器,电路图和出现的问题如附件中所示。 根据芯片手册给出的电荷放大电路,构建了如下所示的电路 但是在使用过程中,6脚输出经常出现尖峰,如下图所示 请问这是什么原因造成的,有什么办法能抑制这种
    发表于 08-30 06:33

    C++语言基础知识

    电子发烧友网站提供《C++语言基础知识.pdf》资料免费下载
    发表于 07-19 10:58 7次下载

    ESP32用send函数发送数据时,经常出现进到send后就出不来了的情况,为什么?

    在使用ESP32的WIFI发送TCP数据时(模块做AP,TCP-Server),用send函数发送数据时,经常出现进到send后就出不来了的情况,唯的解救办法就是断开WIFI连接,send才会返回
    发表于 06-26 07:00

    STM8S003F3经常出现僵死或者是丢程序的问题,怎么解决?

    最近做项目用到STM8S003F3。发现经常出现僵死或者是丢程序的问题。重启无效。使用的IAR开发环境。。重新烧录以后又正常使用。。VCAP上用的是1UF电容。。RST上是4.7K+104。。供电用LDO3.3V应该很稳定。不知道为什么会出现这种问题。。发现
    发表于 05-10 06:37

    如何成为名嵌入式C语言高手?

    文献、参加相关的培训课程、关注行业动态和参与技术讨论是不可或缺的。同时,我们也要勇于挑战自己,接触一些复杂的嵌入式项目,通过实践不断提升自己的编程能力和解决问题的能力。 总结来说,成为名嵌入式
    发表于 04-07 16:03

    细谈SolidWorks教育版的一些基础知识

    SolidWorks教育版是款广泛应用于工程设计和教育领域的三维建模软件。它具备直观易用的操作界面和强大的设计功能,为学生提供了个学习和实践的平台。在本文中,我们将详细探讨SolidWorks教育版的一些基础
    的头像 发表于 04-01 14:35 341次阅读

    如何成为名嵌入式C语言高手?

    文献、参加相关的培训课程、关注行业动态和参与技术讨论是不可或缺的。同时,我们也要勇于挑战自己,接触一些复杂的嵌入式项目,通过实践不断提升自己的编程能力和解决问题的能力。 总结来说,成为名嵌入式
    发表于 03-25 14:12

    C语言的指针用法

    C语言编程中善用指针可以简化一些任务的处理,而对于一些任务(比如动态内存分配),必须要有指针才行的。也就是说精通C指针编程是很有必要的,帮助
    发表于 03-05 14:22 353次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>的指针用法

    介绍C语言中错误处理和异常处理的一些常用的方法和策略

    C语言种低级的、静态的、结构化的编程语言,它没有提供像C++或Java等高级语言中的异常处理
    的头像 发表于 02-28 14:25 620次阅读

    使用HW signal connections 连接不同APP的信号的时候,经常出现信号不能选择的原因?

    使用HW signal connections 连接不同APP的信号的时候,经常出现信号不能选择,或者提示\"DAVE is not able to grant your last hardware resources request\",这是什么原因,能解决吗?
    发表于 02-06 06:27

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

    语言,主要用于开发各种应用程序。尽管PLC编程语言C语言一些相似之处,但它们之间也存在一些
    的头像 发表于 02-05 14:21 4127次阅读