c语言基础知识+OS+数据结构

c语言:

memory section:

.bss:  uninitialized or zero-initialized global and static variables

.data:   initialized global and static variables

.text:    Read only,  code and const

C语言编译流程:

pre-compiler:  #define, #include   【text substitution】

compiler:  turn source code into machine code(object file), perform syntax error check

link:  link these object files together to create an executable file, resolves references to functions or variables that are defined in other object files【map file里面可以看到】

【C语言关键字 / keyword】

Macro写一个函数: Macro本质就是pre-processor将内容进行文本替换

#define SET_BIT(var, position)   var = var | (1<<position)#define MAX(A,B)   (A>B)?A:B

  • short 2bytes
  • long 4 bytes

typedef 和 macro哪个好

const的含义:    Read only

volatile的含义:        tell compiler not to use cache to optimize, always to read from address. 

const 和 volatile公用:         

uint8_t const volatile * reg_1 = (uint8_t *) 0x10000000;

对固定地址赋值

*(unsigned int *)0xFC880000 = 1;

extern: change visible scope

static 修饰

  • 全局变量:  accessible only within the file
  • 局部变量:  variables retain their values between function calls
  • 函数: accessible only within the file

sizeof (sizeof也是个keyword): 返回的是byte数

sizeof(int)

sizeof(Node)            //typedef struct{} Node;


 

【位操作】

&

|

^  (exclusive or)

~:    unsigned int mask = ~(0); 

【数据类型】

数组

字符和字符串

end with \0;  NULL character  

qsort 对数组排序

#include <stdio.h>int compare( const void *a, const void *b)
{return *(const int*)a - *(const int*)b; 
}int main()
{int m[] = {1,3,5,2,6};int num = sizeof(m)/sizeof(m[0]);int size = sizeof(m[0]);qsort( m, num, size, compare);printf("0x%x\n", m[0] );printf("0x%x\n", m[1] );printf("0x%x\n", m[2] );printf("0x%x\n", m[3] );printf("0x%x\n", m[4] );return 0;
}注:
1. compare的返回值永远是int, 但是 如果输入数组是char,那么return那行
就要写成 *(const char*)a 【否则不工作】
2. return 那行的 *(const char*)a,星号不要忘了
3. 三个int 变量,啪啪啪写完朝函数里面放就行了
4. qsort是void类型,没有返回值

malloc 分配空间

void *malloc(size_t size)    //返回的是void型指针char *p;p = (char*) malloc( sizeof(char) * 15 );       //15个元素的空间

结构体/union

data alignment: data will be padding

虽然sBa[20],但是仍然看做是2byte的长度,所以结构体还是以 4bytes的长度 来 alignment的

typedef struct
{int Num;short sDate;char cha[2];short sBa[20];
}Test;

指针

指针类型:

void: 可以指向任何类型, qsort的函数就有用到。使用的时候要记得 强制类型转换

wild: not been initialized to anything

NULL: a pointer which is pointing to nothing 

dangling: A pointer pointing to a memory location that has been deleted (or freed)

没有权限访问该地址,所以*p 直接就报错了

空指针,不指向任何地址。在新建链表的时候会用到

直接对物理地址赋值:

* (int*) 0xFF00CCFF = 1;

或者: 【 地址前的 (int*)不要忘了 】

int *p = (int*) 0xFF8800FF;*p = 1

指针数组:

从上图代码可以看出:

二维数组parr[0][0],可以拆开看成  ( parr[0] )[0], 也就是(arrl)[0];

函数指针:

使用很广,中断向量表里面存的就是函数指针

用的时候:

void(*p)(void);或者
void(*0xF32D0000)(1,2);

typecasting:

int will be promoted to unsigned int

一个数组,再加一个栈顶指针

队列

链表

 【库函数】

strlen(const char* str);void* malloc(size_t size);
void free(void *ptr);void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*));

【恶心的】

auto:  default storage class, for local variable 【storage duration is automatic,be created when the program execution enters the block in which it is defined and destroyed when the block exits】

register:  only for local variables, store in cpu register instead of RAM 【& cannot be used on register variable】

enum:

bit field:

说白了就是 int A 后面带一个 :n 即可

// 定义
typedef struct
{int a;
}A;typedef struct
{int a_bit0 :1 ;int a_bit1 :1 ;int a_bit2 :1 ;int a_bit3 :1 ;int a_reserved :28 ;
}A_bitfield;//使用A m;
m.a;A_bitfield n;
n.a_bit0;

switch case:

Exp1 ? Exp2 : Exp3;

i++ / ++i

0xFF

0b011

%s

%d

%f

char  1bit

short 2bit

int:  4 bytes

short vs long:8 bytes

double: 

float: 

runtime error:  X is local variable

OS:

【核心】

basic/extended task:

  • basic task: 在running状态下,只有terminate和被更高优先级任务抢占,进入ready状态两种 释放cpu的方式 【不涉及等待共享资源的简单任务】【反正我看到的AUTOSAR project里面都是extended task】
  • extended task:在running状态下,有主动释放cpu,进入wait状态的能力【等待共享资源的释放】

deadlock:

前提: 有两个共享的resource A和 B,task 1和2 都需要 A和B 两个资源

task1使用了resource A,然后被task2抢占,task使用了resource B,然后发现resource A不可用,于是进入wait 模式【此时B没有被释放】。 task1拿回cpu控制权继续执行,然后发现 resource B不可用,互相wait

解决: timeout,如果等待时间timeout以后,task需要释放自己的resource

优先级反转:  

Priority Inversion

前提:有一个共享的resource  【优先级3>2>1】

优先级1的task 被 优先级3的task抢占,但task3在执行过程中发现share resource不可用【被task1用着呢】,于是释放了cpu【进入wait,任务就绪表置0,触发scheduler】,scheduler根据任务就绪表让task1继续执行,但此时task2又抢占了task1并执行完成,

解决:临时提升低优先级任务的优先级。 task3在因为resource释放cpu的时候,把持有resource的task1优先级临时提升到3,这样task2 就不能抢占他了

【因为basic task中没法处理share resource,所以只有extended task需要考虑deadlock 和优先级反转】

ECU多核之间通讯:

多核间通讯:  IOC, spinlock

就一个core,task发现resource 不能用的时候,就只应该立刻释放cpu 【mutex + semaphore

多核的时候,才有一个core 来while(1),等待另一个core的task运行完release resource的道理【spinlock】

因为spinlock用于多核cpu,其中一个core一直while(1)等待另一个core释放资源,也无所谓 【Spin locks are a low-level synchronization mechanism suitable primarily for use on shared memory multiprocessors. When the calling thread requests a spin lock that is already held by another thread, the calling thread spins in a loop to test if the lock has become available】

进程间通讯:

mutex VS semaphore

都是用来做进程间同步的,区别是mutex必须是进程自己释放,semaphore可以是别的进程释放,而且可以大于1

  • mutex: 主要的purpose是protect shared resources
  • semaphore: 主要的purpose是notice一个event已经发生了,比如taskA 在等一个semaphore,然后一个传感器触发了ISR,ISR去把semaphore置1了,然后taskA就可以继续执行了,这就是为什么说semaphore可以是别的进程释放

semaphore: 【由计数器和 任务等待表 两部分组成,也就是说每个信号量都有自己的任务等待表】

  1. 如果信号量的值为0,任务进入wait状态,并在任务等待表上面被标记,然后触发scheduler
  2. 当其他任务释放了信号量后,会在该信号量的任务等待表中找到最高优先级的任务,并将其从wait转为ready状态,然后触发scheduler

所以scheduler的工作很简单,在任务就绪表里面找最高优先级的任务【有更高的就上下文切换】

  • 想让任务wait,并交出cpu控制权很简单:把它在任务就绪表自己的格子中置0,在任务等待表中置1,然后触发scheduler即可
  • 想让任务从wait到ready,更简单:把它在任务就绪表自己的格子中置1,在任务等待表中置0,然后触发scheduler即可

说白了extended task,就是task可以【因为共享资源不可用】主动放弃cpu控制权,进入wait状态,让优先级低的先去执行【任务就绪表置0,任务等待表置1】

basic task,task没法自己主动放弃cpu,只能是被动的被其他优先级更高的抢占

任务调度的原理:

scheduler被调用的场景:

  1. timer ISR调用scheduler【周期性的任务切换】
  2. task结束,调用scheduler
  3. extended task因为share resource不可用,放弃cpu进入wait状态,然后触发scheduler

任务就绪表【1张】  + 任务等待表【多张,每个信号量都有自己的1张任务等待表,信号量在被task释放的时候,该task会去该信号量的任务等待表唤醒最高优先级的任务进入任务就绪表,然后触发一次scheduler】

scheduler做的事情:

查找任务就绪表优先级最高的任务,如果需要切换,就context switch切换。否则就继续执行当前任务,开销很小

【杂项】

process/thread

  • process has its own dedicated memory space, consume more resource【硬件MPU保护】
  • Threads within the same process share the same memory and resources

big/little endian

针对超过一个byte的数据而言。most significant byte在低地址的为big endian

检测方法:

int a = 0x12345678;char *p = (char*)&a;    //(char*) 告诉编译器用char类型来解析a地址的数据注:
通过char型指针p变量,获取第一个byte,既可判断

inline 函数

a suggestion to the compiler that it should generate code for the function at the call site, instead of generating a separate function call. for better performance

only a suggestion, compiler will make the final decision 

include <> 和 “” 的区别

<>: 寻找 system path(编译器的安装目录文件夹)

"":  寻找当前project path(当前工程文件夹),找不到再找system path

上电流程/startup phase 

【以下针对嵌入式MCU而言】

单核:

  • reset vector
  • startup code
    • init clock
    • memory setup: copy from FLASH to RAM + init stack pointer(stack信息在linker里面定义的 .lsl文件) (.bss .data 会在 RAM运行, .text还是在FLASH运行)
    • init peripheral: init GPIO, CAN (如果需要bootloader功能的话)
    • system init: 中断向量表初始化,enable 中断
  • main()

【linker里面配置了stack的大小,startup phase把stack pointer指向了该位置, 之后main函数入的就是这个栈。只是说操作系统在任务切换的时候,会把cpu register内该task的信息copy到那个task自己的任务控制块里面零时存起来,保护现场。之后再copy回来,就等于恢复现场,可以继续运行了】

【对于操作系统,每个task都要有自己的任务栈,运行的时候,cpu的stack pointer要指过去,是为了方便任务切换。如果所有task公用一个栈,假如task1先入栈运行,然后被优先级更高的task2抢占,入栈到它上面,然后task2运行一半休眠了,那么就没法access到task1的栈内容了。就算你把task2的栈pop出来去存储,也太麻烦了,消耗时间太多】

多核:

  • 硬件启动master core0, core0去唤醒slave core1,2,3 。【唤醒的含义是硬件初始化+startOS】 在所以核心的OS start以后,会进行第一次同步。 
  • 第一次同步后,各个core会去call application startup hook,然后进行第二次同步。从而确保所有core的OS kernel一起开始运行。
  • 【第一次同步是OS 初始化完成(OS的stack什么的)【EcuM startupOne】,第二次同步是进程初始化完成(OS-Application,Task的堆栈,控制块初始化等等)【EcuM startupTwo】,然后同时开启时间片进行Task调用】

中断向量表:

中断向量表网站链接:(array of function pointers)

  • 一个用来存储各个中断服务函数地址的内存区域
  • 中断向量表区间默认是空着的
  • 用户在c文件里面创建了ISR函数,那么MCU上电的时候,startup code就要根据用户创建的各个ISR的地址,把这些函数地址都注册到 中断向量表 里面
  • 中断向量表在code/FLASH section

Interrupts and exceptions:

  • interrupt: trigger by external event, save context and jump to the ISR

  • system exceptions: trigger by cpu (divided by zero, invalid memory access), save context and jumps to an exception handler routine

下图可以看到,Interrupts and exceptions 都在 中断向量表里面

抢占式: (Preemptive)

  1. Preemptive OSes are often used in real-time systems where tasks must meet strict deadlines. The OS can guarantee that high-priority tasks will run when required.

  2. some preemptive OSes use time slicing, where each task is given a fixed time quantum to run. When the time quantum expires, the task is preempted even if it hasn't finished.

函数入栈流程:

函数入栈流程网站链接:

函数栈从高地址到低地址增长

return address, actual parameters and local variable are pushed into stack【返回地址就是下一行该执行的代码的地址】

ebp, esp  stands for base pointer and stack pointer

一道很好的题目

call by value/reference:

  • by value: a copy of the actual argument's value is passed to the function, any changes made to the parameter (in the function) do not affect the original argument
  • by reference: pointer to the actual argument is passed to the function, It is useful when you want a function to modify the original data

actual and formal parameters:

  • formal: variables or placeholders that are declared as part of a function's definition

  • actual: the values  passed to a function when it is called

context switch:

save the current status of task into control blocks 【register, task stacks】

trigger by interrupt, pre-emptive multi-task, 

reentrant function 

  • can be safely called simultaneously by multiple threads, 
  • Reentrant functions use only local data (variables or memory) and do not rely on global or shared data, do not use static variables

#pragma

memory mapping 的时候,用到过

  • variable placement:
  • code section placement: 

原码,反码,补码

正数的原码,反码,补码都一样

负数的原码:和正数一样,除了符号位置1 【问题,正负数原码相加不为0】

反码(ones' complement):直接把正数的原码反过来【问题,正负数反码相加为0xFFFF】

补码(twos' complement):反码+1 【正负数补码相加不为0】

虚拟内存: paged memory

数据结构:

常见错误

的正确用法:

int a[10] = {0};     //记得将所有元素初始化为0 【有些在线编译器很傻逼】num = num <<4;  // 记得写num =, 单独的num<<4 不会改变num本身的值unsigned int mask = ~0;   //如果要位运算,一定记得是unsigned,要么就直接 (~0)<<8


 

常用:

int a[] = “abcdefg”;

sizeof(a);

printf(“%s\n”,a);

基本上:

  • 数组题,就可以考虑先qsort一下,可能会简单很多

  • 数操作,就是从2进制的角度去看, XOR, 一下什么的。 &1111 就是截取, |0000就是删除

  • 不知道循环次数的时候, while(n) 就很好用

位操作: 

数字题的工具:

  1. 截取: &1111 

  2. 删除: |0000

  3. 半加法: XOR 

  4. 取某一个bit:  n&1         n = n>>1

  5. char型指针可以很方便的操作int型变量的每一个byte 

  6. 二进制字符串转数字: 找到1的位置, n = n| (1<<i) 

  7. 找到的元素,可以用一个数组把下标都存起来,然后再操作

  8. 不知道循环长度,可以 while() 循环

  9. 将某一段bit翻转:  ^1111

  10. 找不同: XOR 的结果为1

第5条:   0x5A5A,5A5A   想变成 0xA5A5,A5A5

第8条:

数组操作:

数组题的工具:

  1. qsort

  2. 删除重复的数: XOR

  3. 有的时候,搞个int型指针,就可以一次操作4个char数组元素

指针:

qsort

链表:

malloc

free

stack:

queue:

递归: 

XOR实现加法

#include <stdio.h>int add( int a, int b)
{int sum = a^b;int new = a&b;if( new==0 ){return sum;}else{return add(sum, new<<1);}
}int main()
{printf("%d\n", add(3,21));return 0;
}

冒泡算法:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/84143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速安装和测试混淆后的IPA文件:使用Ipa Guard的签名和安装功能

​ 目录 转载&#xff1a;怎么保护苹果手机移动应用程序ipa中文件安全&#xff1f; 前言 1. 对敏感文件进行文件名称混淆 ​编辑 2. 更改文件的MD5值 3. 增加不可见水印处理 3. 对html&#xff0c;js&#xff0c;css等资源进行压缩 5. 删除可执行文件中的调试信息 转载&…

kubesphere中间件部署

微服务部署前中间件部署 一、MySQL部署 1.1 使用Docker实现MySQL主从复制 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql/master/log:/var/log/mysql \ -v /mydata/mysql/master/data:/var/lib/mysql \ -v /mydata/mysql/master/conf:/etc/mysql \ -e My…

企业架构LNMP学习笔记59

目录介绍&#xff1a; bin&#xff1a;存放的是启动和关闭tomcat的脚本文件&#xff1b; conf&#xff1a;存放tomcat服务器的各种全局配置文件&#xff0c;其中最重要的是server.xml和web.xml lib: 存放的是tomcat服务器所需要的各种jar文件。java打包类库。 logs&#xff…

Vue项目前端代码防止被调试

项目背景 被安全测试针对了&#xff0c;总是调试我这不太安全的代码。前端代码深度混淆转成十六进制还不行&#xff0c;仍然找到加密方法&#xff0c;对后端数据进行解密。这次就修改了思路换种方法: 我承认阁下很强&#xff0c;但假如, 我是说假如打开控制台是空白页面&…

OSCP系列靶场-Esay-Gaara保姆级

OSCP系列靶场-Esay-Gaara 目录 OSCP系列靶场-Esay-Gaara总结准备工作信息收集-端口扫描目标开放端口收集目标端口对应服务探测 信息收集-端口测试22-SSH端口的信息收集22-SSH端口版本信息与MSF利用22-SSH协议支持的登录方式22-SSH弱口令爆破(待定)22-SSH手动登录尝试(无) 80-HT…

“三高”论文完美复现!基于PSO-VMD-MCKD方法的风机轴承微弱故障诊断,实现早期微弱故障诊断,MATLAB代码实现...

声明&#xff1a;对于作者的原创代码&#xff0c;禁止转售倒卖&#xff0c;违者必究&#xff01; 本期文章思路来自振动测试与诊断期刊的一篇三高论文&#xff0c;点击链接可跳转。https://mp.weixin.qq.com/s/hmmDj5IwpaozeL4F0iI-2g 文章摘要如下&#xff1a; 针对风机滚动轴…

在qml中将一个16进制表示的颜色加上透明度

在qml中&#xff0c;我们在指定控件的颜色时&#xff0c;可以直接通过16进制的字符串来表示&#xff0c;比如"#ff0000"; 这种方式也比较符合UI设计人员的使用习惯。 但是假如要在此颜色的基础上&#xff0c;加个透明度的话&#xff0c;就要重新计算一番&#xff0c;比…

【iOS逆向与安全】插件开发之某音App直播间自动发666

1.目标 由于看直播的时候主播叫我发 666&#xff0c;支持他&#xff0c;我肯定支持他呀&#xff0c;就一直发&#xff0c;可是后来发现太浪费时间了&#xff0c;能不能做一个直播间自动发 666 呢&#xff1f;于是就花了几分钟做了一个。 2.操作环境 越狱iPhone一台 frida ma…

c++ 纯虚函数、抽象类

一、 纯虚函数 抽象类 只要有一个纯虚函数&#xff0c;这个类称为抽象类 抽象类的特点 1、无法实例化 2、抽象类的子类&#xff0c;必须要重写父类中的纯虚函数&#xff0c;否者也属于抽象类 例子一 #include <iostream> #include <string.h> using namespa…

tensorflow cuda gpu 安装

Windows 安装 CUDA/cuDNN 需要注意的是一定要选择 TensorFlow 和 CUDA相匹配&#xff0c;还需要查看下自己GPU的驱动版本&#xff0c;如果不匹配会出现很多问题。GPU驱动的版本可在 NVIDIA控制面板里找到&#xff1a; CUDA个版本与驱动的关系如下&#xff1a; GPU版本的 Tensor…

Laravel框架 - IOC容器详解

IOC 容器代码 好了&#xff0c;说了这么多&#xff0c;下面要上一段容器的代码了. 下面这段代码不是laravel 的源码&#xff0c; 而是来自一本书《laravel 框架关键技术解析》. 这段代码很好的还原了laravel 的服务容器的核心思想. 代码有点长&#xff0c; 小伙伴们要耐心看. …

JMeter断言之JSON断言

JSON断言 若服务器返回的Response Body为JSON格式的数据&#xff0c;使用JSON断言来判断测试结果是较好的选择。 首先需要根据JSON Path从返回的JSON数据中提取需要判断的实际结果&#xff0c;再设置预期结果&#xff0c;两者进行比较得出断言结果。 下面首先介绍JSON与JSON…

【深度学习】LeNet网络架构

文章目录 什么是LeNet代码实现网络架构 什么是LeNet LeNet是一种经典的卷积神经网络&#xff0c;由Yann LeCun等人在1998年提出。它是深度学习中第一个成功应用于手写数字识别的卷积神经网络&#xff0c;并且被认为是现代卷积神经网络的基础。 LeNet模型包含了多个卷积层和池…

Spark

Apache Spark是一种快速、通用、可扩展的大数据处理引擎&#xff0c;旨在处理大规模数据集并进行高效的数据分析。与Hadoop MapReduce相比&#xff0c;Spark具有更高的性能和更丰富的功能&#xff0c;可以处理更复杂的数据处理任务。以下是Apache Spark的一些基本概念&#xff…

idea2023+springboot 热部署配置

pom 中配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency>idea

蓝桥杯每日一题2023.9.21

蓝桥杯2021年第十二届省赛真题-异或数列 - C语言网 (dotcpp.com) 题目描述 Alice 和 Bob 正在玩一个异或数列的游戏。初始时&#xff0c;Alice 和 Bob 分别有一个整数 a 和 b&#xff0c;有一个给定的长度为 n 的公共数列 X1, X2, , Xn。 Alice 和 Bob 轮流操作&#xff0…

Rsync学习笔记2

Rsync&#xff1a; 增量操作&#xff1a; 1&#xff09; server01服务文件变动。 [rootserver03 tp5shop]# rsync -av /usr/local/nginx/html/tp5shop root192.168.17.109:/usr/local/nginx/html/ sending incremental file listsent 88,134 bytes received 496 bytes 177,…

如何评估测试用例的优先级?

评估测试用例的优先级&#xff0c;有助于我们及早发现和解决可能对系统稳定性和功能完整性产生重大影响的问题&#xff0c;助于提高测试质量&#xff0c;提高用户满意度。 如果没有做好测试用例的优先级评估&#xff0c;往往容易造成对系统关键功能和高风险场景测试的忽略&…

黑马JVM总结(十八)

&#xff08;1&#xff09;G1_FullGC的概念辨析 SerialGC&#xff1a;串行的&#xff0c;ParallelGC&#xff1a;并行的 &#xff0c;CMS和G1都是并发的 这几种垃圾回收器的新生代回收机制时相同的&#xff0c;SerialGC和ParalledGC&#xff1a;老年代内存不足触发的叫FullGC…

zabbix自定义监控、钉钉、邮箱报警 (五十六)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、实验准备 二、安装 三、添加监控对象 四、添加自定义监控项 五、监控mariadb 1、添加模版查看要求 2、安装mariadb、创建用户 3、创建用户文件 4、修改监控模版 5、…