热门标签 | 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


推荐阅读
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 《2017年3月全国计算机等级考试二级C语言上机题库完全版》由会员分享,可在线阅读,更多相关《2017年3月全国计算机等级考试二级C语言上机题库完全版( ... [详细]
  • c语言基础编写,c语言 基础
    本文目录一览:1、C语言如何编写?2、如何编写 ... [详细]
  • 利用空间换时间减少时间复杂度以及以C语言字符串处理为例减少空间复杂度
    在处理字符串的过程当中,通常情况下都会逐个遍历整个字符串数组,在多个字符串的处理中,处理不同,时间复杂度不同,这里通过利用空间换时间等不同方法,以字符串处理为例来讨论几种情况:1: ... [详细]
  • C语言的经典程序有哪些
    本篇内容介绍了“C语言的经典程序有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何 ... [详细]
  • Java编程思想一书中第21章并发中关于线程间协作的一节中有个关于汽车打蜡与抛光的小例子(原书的704页)。这个例子主要展示的是两个线程如何通过wait ... [详细]
  • vb.net不用多线程如何同时运行两个过程?不用多线程?即使用多线程,也不会是“同时”执行,题主只要略懂一些计算机编译原理就能明白了。不用多线程更不可能让两个过程同步执行了。不过可 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
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社区 版权所有