嵌入式c语言基础知识 嵌入式c语言和c语言区别

目录基础知识数据类型const 用法作用域与 static 用法extern 用法基础知识嵌入式C语言和普通C语言在语法上几乎没有区别。主要区别是普通C语言的运行环境是在OS上,有很多标准库函数支持调用。分配的内存是计算机的内存,它的处理器是CPU电脑的。在嵌入式环境下,会涉及到底层...

目录

基础知识数据类型const 用法作用域与 static 用法extern 用法

基础知识

嵌入式C语言和普通C语言在语法上几乎没有区别。主要区别是普通C语言的运行环境是在OS上,有很多标准库函数支持调用。分配的内存是计算机的内存,它的处理器是CPU电脑的。在嵌入式环境下,会涉及到底层硬件,而硬件本身没有标准库可以调用,所以开发人员需要使用C语言对硬件进行编程和调试才能使其工作。开发某个芯片,有编译器(或者交叉编译环境),可以分配的内存是芯片的RAM和Flash,处理器是芯片本身的MCU,比如ARM和DSP。

比如C语言程序设计入门课程:打印“Hello World!”,一般C语言编程中,直接调用printf()函数就可以在PC上打印出来;在嵌入式系统中,开发人员需要用C语言调试成功芯片的串口,然后重新实现printf()函数,再调用print。

嵌入式C语言的基本结构和特点;

所有的C语言程序都需要包含***in()函数,代码从***in()函数开始执行;这一条在嵌入式中不一定完全正确,在执行***in()函数之前也有开发者可以操纵的空间,因而开始函数可以不是***in(),例如也可以是myMain()这样的函数,而这所涉及到的知识已经超过基础知识的范围,会在后续详细说明;C语言的语句以用分号“;”结束;C语言的注释有行注释(“//”)和段注释(“/…/”);函数是C语言的基本结构,每个C程序都是由至少一个函数组成;C语言的文件有两种格式:源文件.c文件和头文件.h文件,通常.c文件用于功能函数的实现,而.h文件用于预处理、宏定义和声明等;在嵌入式中,通常将某个硬件模块的功能实现函数及其声明和包含的全局变量声明分别处理到一个.c和.h文件中,例如led.c、hello.c和led.h、hello.h就分别对应于LED灯的功能函数及其声明和hello的功能函数及其声明;我们将这种基于某个模块的独立设计称之为模块化设计,在一个系统中通常是由许许多多的模块共同组成的,因而模块化设计是一个非常科学且非常值得学习的程序设计方法;除了模块化设计,通常嵌入式的编程设计还有层次化设计。在一个工程系统中,硬件驱动仅仅只是第一步,对硬件的应用则是一个功能丰富的系统的更进一步的设计,通常在这一块会设计到例如图像处理、数据处理等算法;我们可以笼统地将一个嵌入式工程系统分为驱动层和应用层。

数据类型

在C语言中,数据类型是指用于声明不同类型的变量或函数的扩展系统。变量的类型决定了变量存储所占用的空,以及如何解释存储的位模式。

在嵌入式系统中,芯片的容量是有限的,与PC相比,通常相对较小。所以,知道变量占用的内存空是嵌入式开发者应该掌握的技能。所以开发者也要掌握不同数据类型不同位数的芯片长度(比如STM32xxx表示这个芯片是32位芯片,STM8xxx表示这个芯片是8位芯片)。

C #中的数据类型如下:

以STM32F103ZE为例,该芯片为32位MCU。该芯片中基本数据类型的数据长度,以及HAL库函数中的定义(stdint.h文件中的定义采用C99标准)如图5.3.2所示。这里建议开发者在开发过程中使用库定义的数据类型来定义变量或函数,比如unsigned char a和uint8_t a。

常量用法

在C中,const关键字是constant的缩写,翻译为常量、常数等。,但const关键字不仅用于定义常量,还可以用于修改数组、指针、函数参数等。

修改变量在C语言中,const用于修改变量。它的功能是将变量声明为只读特性,并保护它们的值不被修改。例如:

const int i = 5;

此示例显示整形变量I是只读的,不能修改;如果要重新赋值,比如i=10就是错误的用法。需要注意的是,当const定义变量时,也必须进行初始化。const可以放在数据类型之前或之后。例如,上面的例子也可以写成:

int const i = 5;

另外,const修饰变量也有保存空的目的。通常编译器不会给普通的const只读变量分配空,而是保存在符号列表中,这样就不需要读写内存,程序执行效率会提高。

装饰阵列

C中的Const也可以修饰数组,例如:

const int array[5] = {0,1,2,3,4 };

或者int const array[5] = {0,1,2,3,4 };

Const关键字修饰数组类似于修饰变量,表示该数组是只读的,不能修改。一旦更改,程序就会出错。例如,如果上面的例子:

array[1]= 10;

程序会提示一个错误。

在C语言中修改指针需要特别注意。有两种形式的常量修改指针。一个用于限制点之间的值为空,不可修改。另一种是受限指针不可修改,例如:

int I = 5;

int k = 10

int const * p1 = & amp我;

int * const p2 = &k;

对于指针p1,const修改p1,即p1指向的空之间的值不能改变,例如p1 = 20是错误的用法;但是p1的值是可以改变的,比如P1 = &k;没有问题。

对于指针p2,const修改p2,即指针本身p2不能改变,但指针和空之间的值可以改变,例如* p2 = 15没有问题,而且p2 = &I;是错误的用法。

修改函数参数

在C语言中,const通过修改函数参数来限制参数,防止参数在函数内部被意外修改。受限参数可以是普通变量或指针变量,例如:

无效资金(常数x) {...x = 10//x的值已经被修改,error} void fun1 (const int * p) {...(* p)++;//P和空之间的值已被修改,错误}

范围和静态用法

在了解static关键字的用法之前,我们需要了解C语言中作用域、局部变量和全局变量的概念。

C变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域。

块是用一对花括号“{}”括起来的代码区域,块中定义的变量具有块的作用域。块范围的可见范围是从定义到包含定义的块的末尾。以前,具有块范围的变量必须在块的开头声明。C99标准放宽了这一限制,允许在块中的任何地方声明变量。例如,不支持C99标准的For循环需要这样编写:

void fun 1(void){ int I = 0;for(I = 0;我<10;i++) {...} }

局部变量I定义在fun函数的开头,然后在for循环中调用。变量I的范围在fun函数内,执行fun函数后会释放。在C99标准下,可以这样写:

void fun 2(void){ for(int I = 0;我<10;i++) {...} }

这样,变量I的作用域在for循环中,当循环结束时,变量就会被释放,说明它的作用域缩小了,这样做的好处是增加了安全性和灵活性。

在fun1函数中,变量I在函数体中声明。我们称这样的变量为局部变量,其有效范围在定义的函数内。函数执行后,变量被释放。如果这个变量是在函数之外定义的,比如:

int k = 0;void fun 3(void){ for(k = 0;k <10;k++) {...} }

我们把函数外定义的变量称为全局变量,它的作用域是当前的源文件和项目。如果其他源文件要调用这个变量,需要在文件中用关键字extern声明,比如extern int k,简单总结一下局部变量和全局变量的特点:

局部变量会在每次声明的时候被重新初始化(如果在声明的时候有初始化赋值),不具有记忆能力,其作用范围仅在某个块作用域可见;全局变量只会被初始化一次,之后会在程序的某个地方被修改,其作用范围可以是当前的整个源文件或者工程;

鉴于两个变量的局限性,引入了静态变量(静态局部变量和静态全局变量),并使用关键字static对其进行修改。其中,静态局部变量符合局部变量的作用域,但具有记忆能力,不会每次活一次就初始化。该功能在用来实现计数功能时非常方便,例如:

void CNT(void){ static int num = 0;num++;}

在这个函数中,变量num是一个静态局部变量,在第一次进入cnt函数时声明,然后进行自加运算,num的值等于1;第二次进入cnt函数时,num不会被重新初始化,变成0,而是保持1,然后自增后变成2,以此类推,其作用域仍在cnt函数内。全局变量将全局变量的范围缩小到只有当前源文件可见,而其他文件不可见。简单的例子如下:

静态int k = 0;void set _ k(void){ k = 1;} void reset _ k(void){ k = 0;} int get _ k(void){ return k;}

静态变量的好处是增强了程序的安全性和健壮性,因为对于变量K,我们假设不期望其他文件有修改变量K的能力,但是其他文件需要变量K的值进行逻辑运算。那么我们可以像上面的例子一样,在源文件中定义一个静态的全局变量,用函数来修改和获取它的值,只提供外部的函数接口。其他文件通过函数接口间接使用这个变量。这也可以提高便携性。

全局变量只在这个文件中可见,所以其他文件也可以定义同名的静态局部变量。比如我们可以在source1.c中定义static int k = 0;同时也可以在source2.c中定义一个静态int k = 0;这样做不会有问题,但是我们完全不建议这样做,因为这样不利于程序的可读性和可维护性,也容易混淆开发。

在C语言中,static关键字可以用来修改函数,除了变量,这样函数只能在这个文件中看到,其他文件无法调用。例如,example1.c文件中有以下定义:

静态void gt_fun(void) {...}

那么gt_fun函数只能在example1.c中调用,在example2.c中不能调用,如果不使用static来修饰这个函数,只需要在example2.c中用extern关键字写出语句extern void gt _ fun(void);可以调用gt_fun函数。

在嵌入式C语言编程中,static是一个非常灵活易用的关键字,可以让程序更加简洁、安全、可移植性更强。这三点是嵌入式系统中非常重要的编程思路,需要认真掌握。

外部用法

上一节提到了extern这个关键字,所以本节将详细讨论这个关键字。在C语言中,extern关键字用来表示一个函数或变量是在其他文件中定义的,提示编译器在遇到这个函数或变量时在其他模块中寻找它的定义,以便extern声明的函数或变量可以被这个模块或其他模块使用。因此,由extern关键字修改的函数或变量是声明而不是定义,例如:

extern关键字还有一个很重要的作用,就是如果要在C++程序中引用C语言中的文件,需要使用以下格式:

# ifdef _ _ cplusplus extern " C " { # endif/* # ifdef _ _ cplusplus */......# ifdef _ _ cplusplus } # endif/* # ifdef _ _ cplusplus */

这段代码的意思是,如果当前环境是C++ (_cplusplus是C++编译器中定义的宏),要编译大括号{}中的内容需要使用C语言的文件格式进行编译,extern“C”是向编译器指示这个函数的语句。

本文来自繁华落尽与君老投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/624223.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 07-07
下一篇 07-07

相关推荐

  • 嵌入式硬件平台有哪些 支持linux系统的主板解决

    对于嵌入式系统来说,软件细节很多,任何语句都可能引入问题,所以软件问题定位的技巧就显得尤为重要。前面讲了如何定位嵌入式系统的硬件问题。这一次,我来说说用什么技巧来定位遇到的软件问题。软件问题具有一定的复杂性,表现形式多种多样,具体分类很难一概而论。因此,我

    2023-07-14 06:36:01
    949 0
  • 嵌入式c语言基础知识 嵌入式c语言和c语言区别

    目录基础知识数据类型const 用法作用域与 static 用法extern 用法基础知识嵌入式C语言和普通C语言在语法上几乎没有区别。主要区别是普通C语言的运行环境是在OS上,有很多标准库函数支持调用。分配的内存是计算机的内存,它的处理器是CPU电脑的。在嵌入式环境下,会涉及到底层

    2023-07-07 20:20:01
    552 0
  • 嵌入式洗碗机哪个牌子好(美的嵌入式洗碗机哪个型号好)

    「全文约3500字|需要8分钟阅读」从装修开始,我就一直期待着搬进新家,但是当我和老公真正搬进新家的时候,才发现装修中的一些“不合理决策”和“鸡肋设计”逐渐开始暴露出来。我最后悔的一件事就是厨房的装修,虽然我不止一次跟老公说一定要装洗碗机。结果他说完全没必要。“

    2023-07-06 10:13:01
    889 0
  • 嵌入式是硬件还是软件

    品牌型号:联想小新Pro13/系统版本:windows10 嵌入式并不是单独的硬件和软件。嵌入式指的就是嵌入式系统,是由硬件和软件组成,能够独立运行的设备。嵌入式系统软件系统包括软件运行环境和操作系统,硬件包括处理器、存储器和其它模块等内容。品牌型号:联想小新Pro13/系统版

    2023-07-01 21:54:01
    203 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信