嵌入式C-1/2


1 进制转化

1.1 二进制0B

逢二进一

1.2 十六进制0X

逢十六进一

1.3 二进制和十六进制转换(8421码)

1位十六进制数 = 4位二进制数,通过8421码计算

二进制数不够4的倍数时补0

  • 比如101 1100,写成0101 1100
    在这里插入图片描述

2 指针

指针就是变量,是用来存放地址的变量,存放在指针中的值都被当做地址来处理
地址是唯一标识一块地址空间的

2.1 * 和&

变量前符号简介详情
什么都不加变量的值根据变量的类型,解析变量所在内存地址中的值
&变量地址获得变量的内存地址
*寻址并解析寻找地址等于变量值的内存,根据变量类型解析这块内存中的值
int a = 0; 					// 定义一个int类型变量a
int* point_a;				// 定义一个指向 int类型变量 的指针
point_a = &a;				//把 变量a 的内存地址 赋值给 point_a

//以下为比喻-------------

Car aodi = ....;			// 有一辆奥迪车,它的颜色是...长...宽.........
Car* carNum;				// 生产一个车牌
carNum = &aodi;				// 把这个车牌挂到车上

2.2 内存中分配

在这里插入图片描述
指针的值其实是一个内存地址值,而不是具体值。具体的值保存在变量 a 中。

printf("%d", &a);				// a 变量的地址, 					0x8004

printf("%d", point_a);			// 变量 point_a 的值 				0x8004

printf("%d", a);				// 变量 a 的值						0

printf("%d", *point_a);			// 变量 point_a 值被按照int解析后的值 0

2.3 指针变量和指向关系

用来保存 指针 的变量,就是指针变量。如果指针变量p1保存了变量 num的地址,则就说:p1指向了变量num,也可以说p1指向了num所在的内存块 ,这种指向关系,在图中一般用 箭头表示。
在这里插入图片描述
上图中,指针变量p1指向了num所在的内存块 ,即从地址0028FF40开始的4个byte 的内存块。

2.4 常指针及常量指针const关键字

有时候我们希望定义这样一种变量,它的值不能被改变,在整个作用域中都保持固定。
例如,用一个变量来表示班级的最大人数,或者表示缓冲区的大小。
为了满足这一要求,可以使用const关键字对变量加以限定。
将 const 变量称为常量(Constant)。
常量一旦被创建后其值就不能再改变,所以常量必须在定义的同时赋值(初始化),后面的任何赋值行为都将引发错误。

#include <stdio.h>
const int a = 20;
int b = 30;
int y;

int *p;
/*
普通指针不能指向常量,可以指向变量
*/

const int *p1;
int const *p2;
/*
常量指针:指针变量可以改变,不能用这个指针修改指针指向的内存的值。
指针可以指向常量,也可以指向变量
*/

int * const p3 = &b;
int const * const p4 = &a;  // 指向常量的常指针。指针指向的值不能被修改(*),指针变量(指向的内存)也不能被修改(p4)
/*
常指针:指针变量的值不能被改变,可以通过常指针修改常指针指向的变量的值,只能指向变量。
定义时候需要初始化,初始化后不能修改,和static定义变量的用法一样
*/


/*
区分常量指针和常指针不能被修改的量的技巧:
const后面的量不能被修改.
例如:
const int *p1;  const后面是*p1,指针指向的值,不能被修改
int * const p3 = &b;  const后面是p3,指针变量的值(内存地址),不能被修改
int const * const p4 = &a;  const后面是*,指针指向的值不能被修改(*);const后面是p4,指针变量的值(内存地址),不能被修改
*/


int main(){
    p1 = &a;
    /*
    &a的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a 的地址
    把 变量a 的内存地址 赋值给 p1,p1指向了a
    */
    // p = &a; // 报错。原因:普通指针:不能指向常量。

    printf("p1: %d\n", p1);  // 4210688

    y = *p1;  // 通过指针p1取出a的值赋值给y
    printf("y: %d\n", y);  // 20

    p1 = &b;  // p1指向了b
    printf("p1: %d\n", p1);  // 4206608

    y = *p1;  // 通过指针p1取出b的值赋值给y
    printf("y: %d\n", y);  // 30

    // *p1 = 50;  //报错。原因:常量指针:不能用这个指针修改指针指向的内存的值。

    printf("p3: %d\n", p3);

    printf("b初始值: %d\n", b);  // 30
    *p3 = 50;  //p3原本指向b,b初始为30。p3为常指针,常指针可以通过指针修改指向的变量的值,也就是修改b的值
    printf("常指针修改了b的值,b: %d\n", b);  // 50

    printf("p3: %d\n", p3);
    return 0;
}

2.5 typedef关键字——函数指针的简化

/*函数指针的简化*/
#include <stdio.h>

/*
typedef关键字的作用:
对现有的类型重命名,不会产生新的类型。
简化复杂的表达式。

typedef关键字的书写规则:
1、用类型定义变量名
2、在定义变量名之前加上typedef关键字
*/

// typedef char INT8;
// INT8 a,b,c;  //相当于char a,b,c

// typedef struct{
//     /* data */
// }PERSON_S;
// PERSON_S p1, p2;


/*
函数指针的使用形式:
1、直接使用函数指针的定义式来定义函数指针变量
2、定义函数指针数组
3、函数的形参含有函数指针(回调函数)
4、函数的返回值是函数指针
5、函数的返回值和函数的形参都含有函数指针。
*/

//1、直接使用函数指针的定义式来定义函数指针变量
typedef int (*PFUN) (int x);
PFUN p1,p2 = cube;

//2、定义函数指针数组
PFUN a[2] = {square, cube}; // 等价于:int (* a[2]) (int x) = {square, cube};

// 3、函数的形参含有函数指针(回调函数)
int f1(PFUN p, int x){  // 等价于:int f1(int (*PFUN) (int x), int x)
    return (*p)(x);
}

// 4、函数的返回值是函数指针
PFUN f2(int x){  // 等价于:int (*f2(int x)) (int x)
    return a[x];
}

// 5、函数的返回值和函数的形参都含有函数指针。
PFUN f3(PFUN p){  // 等价于:int (*f3 (int (*PFUN)(int x))) (int x)
    return p;
}

int y;

int main(){
    int square(int x);
    int cube(int x);

    // PFUN = square;
    // y = (*PFUN)(2);
    // printf("y=2*2=%d\n", y);

    // PFUN = cube;
    // y = (*PFUN)(2);
    // printf("y=2*2*2=%d\n", y);

    y = (*a[0])(2);  //4
    y = f1(square, 3);  //9
    p1 = f2(1);
    y = (*p1)(2);  //8
}

int square(int x){
    return x*x;
}

int cube(int x){
    return x*x*x;
}

3 结构体

在这里插入图片描述

3.1 c语言的集合数据类型

在这里插入图片描述

3.2结构体用法

在这里插入图片描述

3.2.1 x作为变量

在这里插入图片描述

3.2.2 x作为数据类型

在这里插入图片描述

4 位运算

位运算是将数字以二进制形式进行计算的运算符。

与其他运算符不同,C语言中位运算,顾名思义,是以数值的二进制位为单位进行操作的,包含<<(左移)、>>(右移)、~(按位取反)、&(按位与)、|(按位或)、^(按位异或) 共六种运算符。
C语言的六种位运算:
在这里插入图片描述

位运算功能
左移运算符 <<向左(高位)移位,右侧补0;本质是乘以2的N次方
右移运算符 >>向右(低位)移位,左侧补0;本质是除以2的N次方
按位取反 ~如名,即0变1,1变0
按位与 &相对应的两个位都为1则为1,反之为0
按位或 |相对应的两个位至少有一个为1即为1,反之为0
按位异或 ^相对应的两个位相同为0,相异(不同)为1

4.1 六种位运算

4.1.1 按位与(&)

有0为0,全是1为1。
在这里插入图片描述
按位与运算符的作用:

  1. 清零
    我们可以对某一个数与0进行按位与运算,由于两个位都为1才为1,因此最终全部位都变为0,起到清零的作用

  2. 取指定位
    如某些存储场景下,“第13位表示xxxx“”,我们需要取出13位,则可以让原数值与数字7进行按位与运算,得到的结果即是原数值的1~3位的值。

  3. 判断奇偶
    可以发现,数字的奇偶取决于二进制位的最低一位是1还是0,因此只需要与1按位与运算,判断是1是0即可得知奇偶。

4.1.2 按位或(|)

有1为1
在这里插入图片描述
按位或运算符的作用:
对一个数字的指定位,置为1。

如“某个数字的第七位”表示开关,原先是0,需要改为1的状态,即可以将这个数字与64按位或,即可得到第七位变为1,其余位的值依旧不变。

4.1.3 按位异或(^)

相同为0,不同为1
在这里插入图片描述
异或运算符的作用

  1. 指定位数的翻转
    如想对某个数字的低4位进行翻转,则可以将这个数字与15(二进制为00001111)进行按位异或运算,既可以将原数字的低四位进行翻转,即高四位不变,低四位0变1,1变0

  2. 与0异或还是原值
    大家可以自行实验,一个数字与0进行异或,结果还是原值

  3. 交换两个数字
    除了之前我们学习交换两个数字需要第三个变量做中介之外,如今可以通过异或运算进行,代码如下:

#include<stdio.h>
int swap(int *a,int *b)
{
    if (*a!=*b)
    {
        *a=*a^*b;
        *b=*b^*a;
        *a=*a^*b;
    }
    return 0;
}
int main()
{
    int a=5;
    int b=5;
    swap(&a,&b);
    printf("a=%d b=%d\n",a,b);  //a为3,b为5
    return 0;
}

4.1.4 按位取反(~)

01互换
在这里插入图片描述

4.1.5 左移运算(<<)

对应十进制,左移几位,乘几次2。
左移N位的本质是乘以2的N次方。
在这里插入图片描述
在这里插入图片描述

4.1.6 右移运算(>>)

对应十进制,右移几位,除以几次2。
右移N位的本质是除以2的N次方。
在这里插入图片描述
在这里插入图片描述

4.2 交换律和结合律

& | ^满足交换律和结合律
在这里插入图片描述

4.3 例题

输入5个数,两对相同,找出那个不同的数?
在这里插入图片描述
采用位异或(^)运算和他的结合律。

a ^ a = 0;
a ^ 0 = a;
#include <stdio.h>
int main(){
    int n[5];
    printf("输入5个数字:\n");
    for(int i=0; i<5; i++){
        scanf("%d", &n[i]);
    }
    
    int ans = 0;
    for(int j=0; j<5; j++){
        ans = ans ^ n[j];
    }
    printf("落单的数字为:%d", ans);
}

5 单片机的地址和状态

软件 = 地址 + 状态 → 硬件

5.1 STM32F103X8-B数据手册

储存器图
所有地址的起始地址:0X0000 0000
所有地址容量的最大值:0XFFFF FFFF
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.2 STM32F10XXX

29页
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值