嵌入式学习 Day17

 一. 头删和尾删

删除:
free():释放掉malloc开出的空间,注意free不是将空间清零,而是将空间的使用权交还给操作系统自由分配。该空间在没被调用复写掉之前,空间内的值仍原样存在。

1.头删:

void popFront(struct Node *head)
{
   //1.p指针变量 指向首节点
   //2.断开链表     head->next = p->next;
   //3.释放p所在的节点 
   free(p);

2.尾删:

void void popBack(struct Node *head)
{
   //1.p定位到尾节点的前一个节点 
   while (p->next->next != NULL)
   {
     p = p->next;
   }
   //2.释放 p->next
   //3.p所在节点成为了新的尾节点     p->next = NULL;

注意:

1.struct  Node head  -  -  -   创建了头链表,内部不储存数据,地址为null,空间开在栈上(在main函数里创建新的节点,一般都开在堆上)。
2.函数不能返回局部变量的地址,因为局部变量的空间开在栈上,在函数运行完之后,空间销毁,所以只能返回一个值,而不是地址。

二. 预处理

#include <stdio.h>
#define  N 10
预处理命令:  都是以 # 开头的

 
预处理:
  1.宏定义
  2.头文件包含
  3.条件编译 

编辑程序 --vi 
编译程序 --gcc 
运行文件 --a.out

gcc的编译过程:

    .c ---> 机器代码 (0110)

预处理: 把程序中 # 开头的预处理命令 执行了, 形成 --预处理文件 --源代码文件 
    gcc -E main.c -o main.i 
 

编译: 编译成汇编文件 
    gcc -S main.i -o main.s 
 
汇编: 将汇编文件 编译 成 目标文件(机器代码)
    gcc -c mian.s -o main.o 
    
链接: 需要与用到相关库函数进行链接 ,生成最终可执行文件。
   

1.宏定义 

形式:宏名 --标识符 

           #define N 10 
   

注意:
     a. 标识符一般写成大写
     b. 宏对应的值 是一个常量 
     c. 宏定义只是做简单的文本的替换,不做计算 
     d. 宏的嵌套 
     e.最后不能写分号,因为分号也会作为宏值一部分,参与到文本的替换中
     f.#undef 终止宏的定义,后面的代码不能再用这个宏 
     
 (2).带参的宏 


    形式: #define 宏名(参数)   宏值 
    
    避免宏展开的副作用: 能加括号的都加上
    

 注意:
 带参宏:
       文本替换 --- 有可能导致,源代码的体积变大 。
       快 --预处理阶段干 
       编译之后,对应的代码就已经在可执行代码中了
 函数:
       调用 ---- 内存中只有一份代码
       会有时空开销。        


 
 2.文件包含 

 #include <> 
 #include ""

 #include <stdio.h> 
<>   表示包含的文件,在找的时候,直接到编译器默认路径下寻找


#include "/usr/include/test.txt"
""    表示先在当前目录下寻找,若没有再到默认目录下寻找。(多了动作,编译可能会变慢)

怎么用?
系统相关的标准头文件,用<>

自己定义的 ,用 ""

3.头文件重复包含的处理


点.c 源文件  --函数实现 
int isLeapYear(int year)
{
    
}


头文件 .h --- 声明 
extern int isLeapYear(int year); 

三. 位运算

0 1
计算机  
1Byte --存储单位 
1Byte = 8bits


软件控制硬件

编程 -->CPU-->寄存器(位)--硬件关联 

C语言上 位运算 


   运算规则:一假则假   --- 清0 
   
   int a = 0x33;
   
   a & 0x55;
   
   0011 0011
   0101 0101 &
   ----------
   0001 0001 //0x11     

|  
     运算规则:一真则真  ---置1


   int a = 0x33;
   
   a | 0x55;
   
   0011 0011
   0101 0101 |
   ----------
   0111 0111 //0x77


   运算规则: 真假相对

int a = 0x33;
   
 a ~ 
   
   0011 0011 ~
   ----------
   1100 1100 //0xcc 

^ 异或:
  运算规则:  相同为0 不同为1   (同假异真)

用于加密 

0x55  
0x33 

0101 0101 
0011 0011  (0x33)    //异或一次加密
---------
0110 0110  //0x66
0011 0011
----------
0101 0101 //0x55   //异或两次还原

 

左移:<<  
   数值<<位数 

   int a = 0x33;
   a<<1
   0110 0110
    6    6  //左移一位相当于乘以2 

右移:>> 

    数值>>位数

int a = 0x55;

  0000 0000 0000 0000 0000 0000 0101 0101 
   0000 0000 0000 0000 0000 0000 0101 010|1    //右移一位相当于除以2


注意:
  看数据类型 
  有符号类型的数据,此时右移 最高位 补符号位    //算术右移 
  无符号类型的数据,此时右移 最高位 补0      //逻辑右移 

  左移不用区分以上二者

练习: 
  int a = 0xffffffff;
  编写程序,让所有的偶数位 清0

 

置1 操作  --- 或运算 
int a = 0x55;

0101 0101 
0000 1000
-----------
0101 1101 //0x5D

a = a | 1<<3;

练习:
                          3210
   int a = 0x55555555;  //0101 

   所有奇数位置1 
 


练习:
1.不适用第三方变量,实现两个数交换 

int a = 10;
int b = 20;

思路一:

a = a + b; // 10 + 20 = 30 //a
b = a - b; // 30 - 20 = 10 //b 
a = a - b; // 30 - 10 = 20 //a

思路二:

 0000 1010  a
 0001 0100  b
----------
 0001 1110 
 0001 0100
----------
 0000 1010  b
 0001 1110
 ----------
 0001 0100  //
a = a ^ b;  0001 1110  
b = a ^ b;  0000 1010
a = a ^ b;  0001 0100

 

练习:
1.统计int类型中1的个数

int a = 1213; //二进制中1的个数 

  • 44
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值