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

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

3天内不再提示

通过一些附加信息和有用的实现技术对C函数的探索

multisim ? 来源:multisim ? 作者:multisim ? 2020-09-27 11:11 ? 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

在本文中,我们将通过一些附加信息和一些有用的实现技术来结束对C函数的探索。

基本的C函数(例如,一个或两个参数和一个返回值)并不复杂。但是,C函数非常灵活,通过超越基础知识,您可以更轻松地编写代码,并将一些有益的特性引入固件。

1.将函数原型放入头文件中

有时我想知道一个人是否必须是计算机科学专业才能完全理解C语言功能原型。这确实是一个相当复杂的问题。我认为固件工程师可以放心地忽略这些细节,而只需采取以下标准操作:始终为您的功能提供一个原型,并将这些原型放置在头文件中。

函数原型是一行代码,为编译器提供函数自变量和返回值的数据类型。例如:

float ArithmeticMean(char Value1,char Value2,char Value3);

复制代码

实际上,不必包含输入参数的名称,因为此时编译器希望知道的只是数据类型。因此,您也可以按如下方式编写原型:

float ArithmeticMean(char,char,char);

复制代码

我更喜欢包含参数名称,这可能是因为它允许我通过从函数定义中复制和粘贴来创建函数原型。
当函数原型被遗漏或放错位置时,可能会发生奇怪的事情,而根据我的经验,消除这些问题的最简单方法是将所有函数原型放置在项目的所有源文件中包含的头文件中。这样可以确保您可以安全地在任何源文件中使用任何函数,因为在调用每个函数之前,总是会对其进行声明(即,在头文件中)。

例如,以下代码段摘自一个名为“ Project_DefsVarsFuncs.h”的文件。

//function prototypes

void Delay_us(unsigned int DelayCount);

void Delay_10ms(unsigned int DelayCount);

void Delay_seconds(unsigned int DelayCount);

void Update_LCD(unsigned char SensorNumber, unsigned longdisplayValue);

void LCD_Clear_All();

复制代码

此头文件包含在我的源文件中,如下所示:

//-----------------------------------------------------------------------------

// Includes

//-----------------------------------------------------------------------------

#include "Project_DefsVarsFuncs.h"

复制代码

2.将函数声明为静态以避免命名冲突
随着固件项目变得越来越大和越来越复杂,您可能会发现要在不同的源文件中重用相同的功能名称。您可以使用“ static”关键字来完成此操作。如上所述,在这种情况下,您不会将函数原型放置在头文件中。
“ static”关键字将功能范围限制为一个源文件。这使您可以对不同源文件中的不同功能使用相同的功能名称。在下面显示的示例中,该项目需要三个不同的ProcessData()函数-一个用于分析ADC数据,一个用于响应UART命令,另一个用于处理I 2 C消息。

我将“ static”关键字放在函数原型的前面,然后函数原型移到源文件的顶部(即,在由函数体内的处理器指令组成的“正常”代码之前)。
当多个工程师将要从事同一固件项目时,“ static”关键字也很方便。如果两个工程师正在不同的源文件中工作,则使用静态功能可以使工程师A选择功能名称,而不必担心工程师B将为不同功能选择相同名称的可能性。

3.使用指针将数组传递给函数
嵌入式应用程序经常使用数组-传感器读数,ADC值,短ASCII消息等序列。在这种开发环境中,函数似乎有点尴尬,因为您无法将数组传递给C函数。确实,您不能像传递单个变量那样传递数组,但是可以使用指针为函数提供对数组数据的访问权限。
如果将指针作为参数之一,然后在调用函数时传递数组标识符,则函数主体中的语句可以使用该指针读取和修改数组的内容。如果您对此概念感到有些困惑,建议您先阅读有关C语言中数组的文章 ,然后阅读有关指针的第一篇文章。

4.您可以使用指针调用函数
指针是保存内存地址的变量。该地址通常标识变量或数组第零个元素的位置。但是,指针也可以指向函数。

如果您已经阅读了有关C函数的第一篇文章,您就会知道函数存储在代码存储器的特定位置,就像变量存储在数据存储器的特定位置一样。如果存储在指针中的值是函数的起始地址,则可以使用指针来调用该函数。如果更改指针的值使其等于不同函数的起始地址,则可以使用同一指针来调用该不同函数。
以下代码段显示了如何声明可与具有三个char参数和返回类型float的函数一起使用的函数指针。

float(* Ptr_to_Function)(char,char,char);

复制代码

数组标识符本质上是指向数组第零个元素的指针。同样,功能名称被解释为功能的起始地址(在代码存储器中)。因此,可以将函数分配给函数指针,如下所示:

Ptr_to_Function = ArithmeticMean;

复制代码

现在,您可以使用Ptr_to_Function调用函数ArithmeticMean()。以下两个语句是等效的:

Average = ArithmeticMean(Temperature1, Temperature2, Temperature3);

Average = (*Ptr_to_Function)(Temperature1, Temperature2, Temperature3);

复制代码

5.尽可能使用局部变量
我认为,在许多情况下,我们的本能是在源文件的顶部定义所有变量,然后将其保留在该位置。但是,养成在函数中使用局部变量的习惯是很好的。局部变量的范围仅限于定义它的功能。换句话说,变量是在调用函数时创建的,并在函数完成其任务后消失。
我推荐局部变量有两个原因。首先,它们允许您在不同的函数中重用相同的变量名。复杂的项目可能包含许多需要基本变量的功能,例如循环计数器。我喜欢对循环计数器重复使用“ n”,而不是逐步遍历字母表中的所有字母。
其次,使用局部变量可能会导致更快的代码。我不是编译器专家,但是我认为局部变量很可能放在寄存器中而不是存储位置,并且访问寄存器要比访问内存快。

寄存器是处理器的组成部分,可以快速读取和写入数据。

结论

责任编辑:xj

原文标题:在C语言固件中使用功能的五个技巧

文章出处:【微信公众号:multisim】欢迎添加关注!文章转载请注明出处。

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

    关注

    181

    文章

    7633

    浏览量

    142596
  • 固件
    +关注

    关注

    10

    文章

    566

    浏览量

    24116

原文标题:在C语言固件中使用功能的五个技巧

文章出处:【微信号:A1411464185,微信公众号:multisim】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    【「DeepSeek 核心技术揭秘」阅读体验】第三章:探索 DeepSeek - V3 技术架构的奥秘

    存在资源利用率不高的问题,但它是基础探索,让 我看到将模型分段处理以实现流水线作业的初步尝试。 而 GPipe 方法的改进,通过微批次处理减少并行气泡,如同给流水线 “疏通血管”,让计算设备的闲置
    发表于 07-20 15:07

    Debian和Ubuntu哪个好一些

    兼容性对比Debian和Ubuntu哪个好一些,并为您揭示如何通过RAKsmart服务器释放Linux系统的最大潜能。
    的头像 发表于 05-07 10:58 ?449次阅读

    如何添加一些网络上的库到mpy固件的说明或手册教程?

    下有没有关于如何添加一些网络上的库到mpy固件的说明或手册教程? 问题2: 关于mpy的image库在哪里能了解学习内部代码,只了解一些python,想知道怎么从c转换成mpy能调用的,自己写的
    发表于 04-29 08:16

    S32K312通过UART口打印系统信息,是否有使用Printf () 函数打印信息的Demo例程?

    S32K312通过UART口打印系统信息,是否有使用Printf () 函数打印信息的Demo例程?
    发表于 04-11 07:21

    使用RTD5.0.0的s32k312,C40_Ip擦除pflash存在一些问题求解决

    我正在使用 RTD5.0.0 的 s32k312,C40_Ip擦除 pflash 存在一些问题: Erase block0(0x420000-0x500000) failed
    发表于 04-11 06:53

    关于stm32,u8g2菜单之间切换(三)写u8g2的一些必要函数

    byte_cb这个参数直接使用自带的 u8x8_byte_sw_i2c即可,我们只要实现 u8x8_msg_cb gpio_and_delay_cb这个参数写函数: ? uint
    的头像 发表于 03-07 12:53 ?743次阅读
    关于stm32,u8g2菜单之间切换(三)写u8g2的<b class='flag-5'>一些</b>必要<b class='flag-5'>函数</b>

    同样是函数,在CC++中有什么区别

    同样是函数,在 CC++ 中有什么区别? 第个返回值。 C语言的函数可以不写返回值类型,
    的头像 发表于 11-29 10:25 ?1006次阅读

    一些常见的动态电路

    无论是模电还是数电,理论知识相对来说还是比较枯燥,各种电路原理理解清楚不算容易,换种生动形象的方式或许会增加一些趣味性,也更容易理解这些知识。下面整理了一些常见的电路,以动态图形的方式展示。 整流
    的头像 发表于 11-16 09:26 ?1253次阅读
    <b class='flag-5'>一些</b>常见的动态电路

    分享一些常见的电路

    理解模电和数电的电路原理对于初学者来说可能比较困难,但通过一些生动的教学方法和资源,可以有效地提高学习兴趣和理解能力。 下面整理了一些常见的电路,以动态图形的方式展示。 整流电路 单相桥式整流
    的头像 发表于 11-13 09:28 ?899次阅读
    分享<b class='flag-5'>一些</b>常见的电路

    如何优化SUMIF函数的效率

    在Excel中, SUMIF 函数个非常有用的工具,它可以根据指定的条件对数据进行求和。然而,在处理大量数据时, SUMIF 函数可能会变得效率低下。以下是
    的头像 发表于 11-11 09:20 ?1535次阅读

    使用C语言实现函数模板

      用C语言能不能实现个通用的函数,既能完成整数的相加,又能完成浮点数的相加?
    的头像 发表于 11-09 11:38 ?1030次阅读

    探索设计稿自动生成Flutter代码的技术方案

    作者:京东物流 冷先锋 近年来,随着人工智能和大模型技术的发展,设计稿(UI视图)自动生成代码的技术也在不断进步。本文将探讨几家知名企业在这领域的探索和实践,包括美团、京东、微软等,
    的头像 发表于 11-08 10:09 ?1770次阅读
    <b class='flag-5'>探索</b>设计稿自动生成Flutter代码的<b class='flag-5'>技术</b>方案

    SUMIF函数与SUMIFS函数的区别

    SUMIF函数和SUMIFS函数都是Excel中用于条件求和的函数,它们可以帮助用户根据特定的条件对数据进行求和。尽管它们的基本功能相似,但在使用场景和功能上存在一些差异。以下是对这两
    的头像 发表于 10-30 09:51 ?8085次阅读

    GPIO Init函数结尾没有begin end用户编辑区域,为什么?

    MX_GPIO_Init初始换函数结尾没有begin end用户编辑区域,但是在其他初始化函数后有编辑区域,并且在main.c文件每个初始化后方也没有用户编辑界面,如果想要在初始化结尾
    发表于 09-26 06:08

    LED驱动器应用的一些指南和技巧

    电子发烧友网站提供《LED驱动器应用的一些指南和技巧.pdf》资料免费下载
    发表于 09-25 11:35 ?0次下载
    LED驱动器应用的<b class='flag-5'>一些</b>指南和技巧