热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

推荐给你17条C语言编程小知识

1.流水线被指令填满时才能发挥最大效能,即每时钟周期完成一条指令的执行(仅指单周期指令)。如果程序发生跳转,流水线会被清空&

1. 流水线被指令填满时才能发挥最大效能,即每时钟周期完成一条指令的执行(仅指单周期指令)。如果程序发生跳转,流水线会被清空,这将需要几个时钟才能使流水线再次填满。因此,尽量少的使用跳转指令可以提高程序执行效率,解决发案就是尽量使用指令的“条件执行”功能。

2. 在LPC2200系列中:

可以通过过下面的程序延迟10毫秒:

for(i&#61;0;i<200;i&#43;&#43;)
{
for(j&#61;0;j<200;j&#43;&#43;);
}

3. 通过下面语句将一个16位的变量放在两个8位的变量中。

//IP数据报总长度高字节

IpHeadUint8[10]&#61;(IpHead.e_ip.Crc&0xff00)>>8;

//IP数据报总长度低字节

IpHeadUint8[11]&#61;IpHead.e_ip.Crc&0x00ff;

4. 在对全部数组元素赋初值时&#xff0c;可以不指定数组长度。

eg;inta&#61;{1,2,3,4,5};

但如果当输出第a[5]以上的元素时&#xff0c;系统回输出随机数值&#xff0c;所以使用此方法时&#xff0c;不能使用超过初始值元素以上的元素。

5. 由于ADS先天性的对printf不支持;因此不便于我们调试&#xff0c;可以利用串口输出来代替printf来调试。

6. 用或运算&#xff0c;可使某位置为1&#xff0c;其它位不变

eg: PINSEL0 |&#61; 0x00000005; //设置串口引脚

使第0位和第二位置一&#xff0c;其他位不变。

7. 函数指针

1> C语言中函数名直接对应于函数生成的指令代码在内存中的地址&#xff0c;因此函数名可以直接赋给指向函数的指针。

2> 调用函数实际上等同于“调用指令&#43;参数传递处理&#43;回归位置入栈”&#xff0c;本质上最核心的操作是将函数生成的目标代码的首地址赋给CPU的PC寄存器。

3> 因为函数调用的本质是跳转到某一个地址单元的code去执行&#xff0c;所以可以“调用一个根本就不存在在函数实体。

4> int (*p);定义p是一个指向函数的指针变量&#xff0c;次函数返回带回整型的返回值。*P两侧的括号不能省略&#xff0c;表示p先于*结合&#xff0c;是指针变量&#xff0c;然后再与后面的结合&#xff0c;表示此指针指向函数。

区别&#xff1a;int *p表示这个函数的返回值是指向整型变量的指针。

说明&#xff1a;

(1) 指向函数的指针变量的一般定义形式为&#xff1a;

数据类型 (*指针变量名);

1> 此处的“数据类型”是指函数返回值的类型

(2) 返回指针值的函数&#xff1a;

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

eg: int * func(int x,int y)

func是函数名&#xff0c;调用它以后能返回一个指向整型数据的指针。x,y是func的形参。

区别方法&#xff1a;

a.从右往左找第一个括号&#xff0c;括号里面的是函数的形参。

b.括号外面的第一个标识符是函数的名字&#xff0c;函数前面的表示函数的返回数值。

8. 数组指针

1>int (*p)[4]

表示*p有4个元素&#xff0c;每个元素为整型。也就是p所指的对象有4个整型元素的数组&#xff0c;既P是行指针。

2> 指针数组

Ø 一个数组&#xff0c;其元素均为指针类型数据&#xff0c;称为指针数组;即指针数组中的每一个元素都相当于一个指针变量。

Ø 一维指针数组的定义形式为&#xff1a;

类型名 *数组名[数组长度]

eg&#xff1a;int *p[4]:

作用&#xff1a;它用于指向若干个字符串&#xff0c;使字符串处理更加方便灵活。适用于一个二维字符串数组&#xff0c;其中每一行的字符数组的长度各不相同

eg:char * name&#61;{“Follow me”,”BASIC”,”GreatWall”};

9. 结构体

1> 可以用结构体变量做实参。但是用结构体变量作实参时&#xff0c;采取的是“值传递”的方式&#xff0c;将结构体变量所占的内存单元的内容全部顺序递给形参。形参也必须是同类型的结构体变量。

eg:pint(su);//注在此处su为结构体

注&#xff1a;这种传递方式在空间和时间上开销较大&#xff0c;如果结构体的规模较大时&#xff0c;开销是很可观的。

2> 用直向结构体变量(或数组)的指针作实参&#xff0c;将结构体变量(或数组)的地址传给形参

eg:print(&su);//注在此处su为结构体

10. 共用体

1> 共用体把几种不同数据类型的变量存放在同一块内存里。公用体中的变量共享同一块内存。

2> 定义公用体类型变量的一般形式为&#xff1a;

union 共用体名

{

成员列表;

}变量列表;

3>在共用体中同一块内存可以用来存放几种不同类型的数据&#xff0c;但在某一时刻只能在其中存放一个成员变量。共用体变量中起作用的成员是最后一次存入的数据。

eg: union data
{
int i;
char c;
double d;
};
union data a;

共用体变量a中的成员i,c,d三个变量在内存中从同一个地址开始存储。如进行如下赋值&#xff1a;

a.i &#61; 100;

a.c &#61; ‘A’;

那么此时共用体变量a中的成员i已经没有值了&#xff0c;因为存储该值的内存现在已经被用来存储成员c的值了。

3> 共用体变量的长度取决于其成员的最大长度&#xff1a;

说明&#xff1a;

结构体变量所占内存的长度是各个成员的总和&#xff0c;每个成员分别占有自己的存储空间。共用体变量所占内存的长度是其最长成员的长度。当然&#xff0c;编译器出于提高访问效率的目的&#xff0c;在编译分配存储空间时往往要进行对齐操作。

对齐操作以最大基本类型为准。即以最大基本类型为基本单元。若按实际算下的长度不是基本单元的整数倍&#xff0c;则其实际长度应该是基本单元的整数倍。

(在TurboC中不进行对齐&#xff0c;在Linux中进行对齐)

11. CPU字长与存储器位宽不一致处理

例如&#xff1a;使用共用体来解决这一冲突&#xff1a;

union send_temp{

uint16 words;

uint8 bytes[2];

}send_buff;

eg:send_buff.bytes[0]&#61;a;//此处a 是8位

send_buff.bytes[1]&#61;b;//此处 b 是8位;

此时就将8位字拼成了16位字存储了。

发送时send(send_buff.words)就可以每次发送一个16位的数据了。

12. C语言符号优先级&#xff1a;

1>复合赋值运算符号&#xff1a;

a&#43;&#61;3*5;

等价于a&#61;a&#43;(3*5);

13.一个常见的调试策略是把一些printf函数的调用散布于程序中&#xff0c;确定错误出现的具体位置。但是&#xff0c;这些函数调用的输出结果被写入到缓冲区中&#xff0c;并不立即显示于屏幕上。事实上&#xff0c;如果程序失败&#xff0c;缓冲输去可能不会被实际写入&#xff0c;因此得到的错误位置就是错误的。解决的方法是在每个用于调试的printf函数之后立即调用fflush函数即可得到。

printf(“something or other”);
fflush(stdout);

14.关键字volatile的用法

volatile变量可能用于如下几种情况&#xff1a;

1>设备的硬件寄存器(如&#xff1a;状态寄存器)

2>一个中断服务子程序中会访问到的全局变量

3>多线程应用中被几个任务共享的变量。

15.关键字register的用法&#xff1a;

当对一个变量频繁被读写时&#xff0c;需要反复访问内存&#xff0c;从而花费大量的存取时间。为此&#xff0c;C语言提供了一种变量&#xff0c;即寄存器变量。这种变量存放在CPU的寄存器中&#xff0c;使用时&#xff0c;不需要访问内存&#xff0c;而直接从寄存器中读写&#xff0c;从而提高效率。寄存器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复使用的变量均可定义为寄存器变量&#xff0c;而循环计数是应用寄存器变量的最好候选者。

(1) 只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式&#xff0c;凡需要采用静态存储方式的量都不能定义为寄存器变量&#xff0c;包括&#xff1a;模块间全局变量、模块内全局变量、局部static变量;

(2) register是一个"建议"型关键字&#xff0c;意指程序建议该变量放在寄存器中&#xff0c;但最终该变量可能因为条件不满足并未成为寄存器变量&#xff0c;而是被放在了存储器中&#xff0c;但编译器中并不报错(在C&#43;&#43;语言中有另一个"建议"型关键字&#xff1a;inline)。

16.对于程序代码&#xff0c;已经被烧录在FLASH或ROM中&#xff0c;我们可以让CPU直接从其中读取代码执行&#xff0c;但通常这不是一个好办法&#xff0c;我们最好在系统启动后将FLASH或ROM中的目标代码拷贝入RAM中后再执行以提高取指令速度。

CPU对各种存储器的访问速度&#xff0c;基本上是&#xff1a;

CPU内部RAM > 外部同步RAM > 外部异步RAM > FLASH/ROM

17. 宏定义

在C语言中&#xff0c;宏是产生内嵌代码的唯一方法。对于嵌入式系统而言&#xff0c;为了能达到性能要求&#xff0c;宏是一种很好的代替函数的方法。

1>宏定义“像”函数;

2>宏定义不是函数&#xff0c;因而需要括上所有“参数”;

3>宏定义可能产生副作用。因而不要给宏定义传入有副作用的"参数"。

END


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了基于c语言的mcs51单片机定时器计数器的应用教程,包括定时器的设置和计数方法,以及中断函数的使用。同时介绍了定时器应用的举例,包括定时器中断函数的编写和频率值的计算方法。主函数中设置了T0模式和T1计数的初值,并开启了T0和T1的中断,最后启动了CPU中断。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
author-avatar
雅白斋ab
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有