嵌入式C语言——学习笔记

嵌入式C语言——学习笔记1

一、位运算

符号 运算规则
&(与) 两个位都为1时,结果才为1(从真假方面看,只有当两个位都为真时,结果才为真)
\(或) 两个位都为0时,结果才为0 (从真假方面看,如果两个运算对象中相应的一个位为真或者两个位都为真,那么结果为真)
^(异或) 两个位相同为0,相异为1(从真假方面看,如果两个运算对象中相应的一个位为真且不是两个位同为1,那么结果为真)
~(取反) 0变1,1变0
<< (左移) 各二进位全部左移若干位,高位丢弃,低位补0
>>(右移) 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)

掌握了这六种操作否的用法,C语言的位操作就差不多了。这六种操作符的解释如下:

1、 & 按位与: 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0。
例如: 1&1 = 1 1&0 = 0 0&1 = 0 0&0 = 0

2、| 按位或:两个相应的二进制位中只要有一个为1,该位的结果值为1。
例如: 1|1 = 1 0|1 = 1 1|0 = 1 0|0 = 0

3、^ 按位异或: 若参加运算的两个二进制位值相同则为0,否则为1。
例如: 1^1 = 0 0^1 = 1 1^0 = 1 0^0 = 0

4、~ 取反: 对一个二进制数按位取反,即将0变1,将1变0。
例如: 1! = 0 0! = 1

5、<< 左移:用来将一个数的各二进制位全部左移N位,右补0。
例如: 00001100 << 2 = 00110000

6、>> 右移:将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0。
例如: 00001100 >> 2 = 00000011

二、静态变量(static)

static最主要有以下两点用途:

1、让一个变量长期有效,而不管其是在什么地方被申明。

例如:

int fun1() 
{
      
static int s_value = 0;. 
}

fun1不管在什么地方被调用,当函数退出后,s_value最后的值将一直会被系统保存,下次s_value再被用到时,也即当fun1()再次被调用时,s_value初始值将是最近被保存过的值(请注意s_value初始化操作只会被执行一次,即上述s_value =0 这个语句)。

2、避免多个文件使用了相同的变量名而导致冲突 。

在C语言中static的作用如下:

第一、在修饰变量的时候,static修饰的静态局部变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放;
第二、static修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以;
第三、static修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。Static修饰的局部变量存放在全局数据区的静态变量区。初始化的时候自动初始化为0。

static int st_val;                   //静态全局变量 -- 静态存储区
int ex_val;                           //全局变量 -- 静态存储区int main(void)
{
     
   int a = 0;                         //局部变量 -- 栈上申请
   int *ptr = NULL;                   //指针变量
   static int local_st_val = 0;       //静态变量
   local_st_val += 1;
   a = local_st_val;
   ptr = (int *)malloc(sizeof(int)); //从堆上申请空间
   if(ptr != NULL)
   {
           
    printf("*p value:%d", *ptr);
    free(ptr);      
    ptr = NULL;      
    //free后需要将ptr置空,否则会导致后续ptr的校验失效,出现野指针   
    }            
} 

C语言的作用域不仅描述了标识符的可访问的区域,其实也规定了变量的存储区域,在文件作用域的变量st_val和ex_val被分配到静态存储区,其中static关键字主要限定变量能否被其它文件访问,而代码块作用域中的变量a, ptr和local_st_val则要根据类型的不同,分配到不同的区域,其中a是局部变量,被分配到栈中,ptr作为指针,由malloc分配空间,因此定义在堆中,而local_st_val则被关键字限定,表示分配到静态存储区,这里就涉及到重要知识点,static在文件作用域和代码块作用域的意义是不同的:在文件作用域用于限定函数和变量的外部链接性(能否被其它文件访问), 在代码块作用域则用于将变量分配到静态存储区。

静态变量常用使用方式:
定义局部变量:用static声明后的局部变量的值在函数调用结束后不消失而保持原值,其占用的是静态存储区,所以即其占用的存储单元不释放。典型应用是用static变量求阶乘n!。

// 求阶乘 n!
int fac(int)
{
     
   static int f = 1 ;
   f = f * n ;
   return f ;
}
main()
{
     
   int i ,n  ;
   float sum;
   scanf("%d",&n) ;
   for(i = 1 ;i <= n ;i++)
   {
     
       sum = fac(i) ;
   }
   printf("输出%d!= %f ",n,sum)}

三、extern变量声明
C 语言中 extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里面要注意,对于 extern 申明变量可以多次,但定义只有一次。
例如:

extern u16 USART_RX_STA;

这个语句是申明 USART_RX_STA 变量在其他文件中已经定义了,在这里要使用到。

四、关键字const

const int a;    //整型常数
int const a;    //整型常数
const int *a;   //指向整型常数的指针(整型常数不能修改,指针可以)
int * const a;    //指向整型数得常指针(指针指向的整型数可以修改,指针不能修改)
int const * a const;    //指向整型常数的常指针(指针指向的整型数不能修改,同时指针也不能修改)

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思 a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

const关键字注意:
1、const关键字修饰的变量可以认为有只读属性,但它绝不与常量划等号。
例如:

const int i=5; 
       int j=0; 
       ... 
       i=j;   //非法,导致编译错误,因为只能被读 
       j=i;   //合法 

2、const关键字修饰的变量在声明时必须进行初始化。
例如:

const int i=5;    //合法 
     const int j;      //非法,导致编译错误 

3、C标准中,const定义的常量是全局的。

你可能感兴趣的:(嵌入式c,c++)