嵌入式C-12

嵌入式C-12,第1张

嵌入式C-1/2

文章目录

1 进制转化

1.1 二进制**0B**1.2 十六进制**0X**1.3 二进制和十六进制转换(8421码) 2 指针

2.1 * 和&2.2 内存中分配2.3 指针变量和指向关系2.4 常指针及常量指针const关键字2.5 typedef关键字——函数指针的简化 3 结构体

3.1 c语言的集合数据类型3.2结构体用法

3.2.1 x作为变量3.2.2 x作为数据类型 4 位运算

4.1 六种位运算

4.1.1 按位与(&)4.1.2 按位或(|)4.1.3 按位异或(^)4.1.4 按位取反(~)4.1.5 左移运算(<<)4.1.6 右移运算(>>) 4.2 交换律和结合律4.3 例题 5 单片机的地址和状态

5.1 STM32F103X8-B数据手册5.2 STM32F10XXX


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 
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)






int main(){
    p1 = &a;
    
    // p = &a; // 报错。原因:普通指针:不能指向常量。

    printf("p1: %dn", p1);  // 4210688

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

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

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

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

    printf("p3: %dn", p3);

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

    printf("p3: %dn", p3);
    return 0;
}
2.5 typedef关键字——函数指针的简化
#include 



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

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




//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=%dn", y);

    // PFUN = cube;
    // y = (*PFUN)(2);
    // printf("y=2*2*2=%dn", 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。

按位与运算符的作用:

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

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

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

4.1.2 按位或(|)

有1为1

按位或运算符的作用:
对一个数字的指定位,置为1。

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

4.1.3 按位异或(^)

相同为0,不同为1

异或运算符的作用

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

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

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

#include
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=%dn",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 
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页


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5718753.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存