C语音高效进阶

C语音是我们进行嵌入式和跟硬件打交道最常用的语音,在开发中有不少注意事项,在此做个笔记记录一下

变量

一个变量只能定义一次 如果在一个文件中定义变量,需要在另一个文件中使用,如全局变量,需要在使用的文件中做加关键字 extern 做一次声明如:

a.c文件
int a=0;//变量定义

b.c文件中使用a变量
extern int a;//变量声明

告诉编译器b.c文件中的 变量a 不是在当前文件中定义的,我在这里只是用一下而已,你需要到别的文件中去找定义 变量的定义会给变量开辟内存空间,声明则不会,开辟的内存空间大小跟变量的类型相关

sizeof

sizeof 是用来计算变量或数据类型所占内存空间大小的关键字,注意它不是函数,它的单位是字节,如果计算的是变量的类型可以使用sizeof 或 sizeof()如:

int a=20;
printf("int size= %ul",sizeof(a)) //或者 printf("int size= %ul",sizeof a)

如果计算的对象是数据类型则必须用sizeof(),也就是必须加括号,所有我们在使用sizeof时,基本上用sizeof() 如果计算的数据类型为指针的话,计算结果是指针类型的大小,并不是指针指向的数据类型的大小

float浮点型

1、尽量不要拿一个float类型的数据跟另一个float类型的数据比较是否相等,容易出问题 2、float类型的数据有效位为7位,这7位包括整数位和小数位 3、不要用很大的浮点数和很小的浮点数运算,否则编译器可能会丢弃掉那个较小的数,会产生计算结果的错误

变量定义与赋值

变量的定义初始化和赋值的区别,变量的初始化是在编译阶段就已经进行静态赋值了,不占用CPU时间,变量赋值是CPU在运行的过程中动态赋值的需要占用CPU时间

int a=10;//变量定义初始化

int b;//变量动态赋值
b=10

所以为了让代码运行效率更高最好是在定义变量的时候直接初始化

整形变量在内存的存储形式

32位系统 数字8的存储形式为:

原码:0000 0000 0000 0000 0000 0000 0000 1000

补码:0000 0000 0000 0000 0000 0000 0000 1000

数字-8的存储形式为:

原码:1000 0000 0000 0000 0000 0000 0000 1000

补码:1111 1111 1111 1111 1111 1111 1111 0111 +1 = 1111 1111 1111 1111 1111 1111 1111 1000

整数在内存中是以二进制存储的,以补码的形式表示 一个正数的补码和原码相同

一个负数的补码 符号位不变,数据位取反后+1

const关键字

const 定义一个常量,这个常量必须在定义时初始化,否则就没机会了 实际const定义的变量并不是真正的一个常量(通过指针可以验证) const 和指针的用法

const int *pt;
int const *pt;
//两者相同,都代表pt 指针可以指向任意对象,但是不能通过指针修改被指向的对象

int *const pt;//pt 指针不能指向其他位置,但是可以修改指向位置的值

const 修饰形参如:

int add(const int *a,const int *b)

循环的优化

for(i=0;i<N;i++)
{
    if(condition)
        run_this_code();
    else
       run_that_code(); 
}

if(condition)
{
     for(i=0;i<N;i++)
         run_this_code();   
}
else
{
     for(i=0;i<N;i++)
        run_that_code();
}

其中下面的写法运行效率比上面的写法运行效率高

数组和指针

数组内部数据在内存中是联系存储的,数组名称可以认为是指向第一个数组元素的指针,他们的表现形式一样,但是数组不是指针 对指针进行自增运算是指移动指针指向下一个相邻位置,对数组[index]进行自增也是指向数组下一个元素的位置,所有表现形式一样

指针存储的永远都是一个地址,只是这个地址可以是任意类型的地址

define和typedef的区别

typedef 是对数据类型的别名 define是一种编译替换

宏不是函数

宏可以提高运行速度,避免额外开销 加括号(参数、整体)避免副作用(++,--)

位操作

位清零用 &操作

*(unsigned long *)0x40010800 &= 0xFFF0000F //清除寄存器的[19:4]位

置位用 | 操作

*(unsigned long *)0x40010800 &= 0x00033330 //[19:4]=0011 0011 0011 0011

二进制 1111 = (1<<1)(|1<<2)|(1<<3)|(1<<4)

二进制 0000 = ~((1<<1)(|1<<2)|(1<<3)|(1<<4))

结构体

结构体在内存中也是连续存储的

取位

在开发中经常会遇到取出几位数据的情况,用&操作即可比如

1001101010110010 & 0000000000000100(0x4)=0 //第2位数据为0

1001101010110110 & 0000000000000100(0x4)=1 //第2位数据为1

这样就可以得到第二位数据

取出多位数据 比如取出 [14:3]位的数据可以用移位操作 先左移1位后右移动4位

1[101010110101]011  <<1= [101010110101]0000 >>4= 0000[101010110101]

这样就取出[14:3位的数据了]

文档信息

版权声明:可自由转载(请注明转载出处)-非商用-非衍生

发表时间:2020年9月16日 20:30