C
文章平均质量分 68
C语言
GK小卜
这个作者很懒,什么都没留下…
展开
-
stm32 freertos任务切换,多任务状态迁移,中断临界段,任务延时,中断过程,普通中断与任务切换的区别
arm中SP,LR,PC寄存器以及其它所有寄存器以及处理器运行模式介绍一、xTaskCreate()1、prvInitialiseNewTask()2、prvAddNewTaskToReadyList()(1):全局任务计时器uxCurrentNumberOfTasks加一操作。uxCurrentNumberOfTasks 是一个在task.c中定义的静态变量,默认初始化为0(2):如果pxCurrentTCB为空,则将pxCurrentTCB指向新创建的任务。pxCurrentTCB 是一个在t原创 2023-07-06 14:20:14 · 1582 阅读 · 0 评论 -
stm32数据对齐、PRESERVE8、freertos的heap堆栈、
避免数据在内存中跨边界存储,减少读取数据次数,提高效率,本质上是以空间换时间的做法CPU数据线有32位一次最多可以从内存读取32数据,这里的一次指一次存储周期LDR r1 , [pc,#4], 是从pc+#4地址处开始连续读取4个字节的数据到r1寄存器LDRH r1 , [pc,#4], 是从pc+#4地址处开始连续读取2个字节的数据到r1寄存器LDRB r1 , [pc,#4] 直接取pc+#4当前那个地址的数据上述指令都是在一个存储周期里完成的。原创 2023-06-22 11:37:39 · 2328 阅读 · 0 评论 -
回调函数与钩子函数的区别,另QT中connect函数的实现,lambda的使用
这两种函数的区别,简单说,其实就是钩子函数不一定会用到,而回调函数一定会用到,因为钩子函数是要等待某种状态发生才会用到,这种状态不一定会发生,而回调函数是为了某个目的设置的,只要这个目的是必须的就一定会调用到。2、lambda表达式[]的捕获赋值,可以节省临时变量的赋值,原理就是lambda创建了一个类,[ ]里的捕获赋值只会初始化一次,详见上述参考链接。信号的参数数量必须大于等于槽函数的参数数量,信号的参数和槽函数的参数必须得兼容(类型一致或可以转化),信号槽的返回值的类型也必须得兼容。原创 2023-06-02 23:33:33 · 552 阅读 · 0 评论 -
通过stm32汇编来看C语言数组内存分配
数组中的元素是字面量,编译后就保存在0x080010f0 flash的RO code中。运行到该处的程序时,在栈中开辟空间(sub sp指令)将字面量保存到栈中。分配完后可以看到在栈地址0x200013b8处看到该数组存放的元素值。先给栈中高地址分配数组高位元素,再给栈中低地址分配数组低位元素。一个u8 test的数组。原创 2023-05-21 12:23:54 · 133 阅读 · 0 评论 -
stm32定时器PWM输出
【STM32】通用定时器的PWM输出(实例:PWM输出)注意点:在复用重映射引脚功能时,如果是输出,那么对该引脚的GPIO初始化必须开启为复用推挽或复用开漏模式,而如果是输入就没有这个必要,但都要打开相应的重映射寄存器AFIO上面代码中先给AFIO时钟使能,在调用引脚重映射函数与我的文章中断模型中给EXTI外部线中断是一个道理,如下:...原创 2021-10-17 23:22:07 · 569 阅读 · 0 评论 -
stm32中断模型和中断初始化(EXTI、NVIC、timer、AFIO)
从stm32的架构图可以看到,挂载在APB2上的外设有GPIO、EXTI、AFIOGPIO的所有引脚默认是与输入输出寄存器相连映射的AFIO算是一个不是外设的外设,因为它主要是用来将引脚重映射到其它外设寄存器的,但是对它操作也需要开启相应的时钟,所以也就放在了这里从引脚到->EXTI中断控制器->NVIC控制器的整个硬件架构通用I/O端口以下图的方式连接到16个外部中断/事件线上,配置AFIO_EXTICRx寄存器该部分主要是将引脚重映射到终端线上,也就是下下个图里的输入线但是再这.原创 2021-10-07 00:13:59 · 3391 阅读 · 1 评论 -
stm32启动过程、cortex-m3架构、堆栈代码位置、编译汇编链接分析
分析一、 寄存器、架构、工作流程1、 寄存器架构复位有三种启动方式,从哪里开始启动、启动代码的所在的位置一、 寄存器、架构、工作流程1.这里以stm32的架构:cortex-m3(也即ARMv7)的寄存器的作用、在指令取,指令的译码,指令的执行在其中的作用以及是如何配合实现代码的执行的哈佛结构和冯诺依曼结构是如何体现的?编译后的代码为什么分为code、堆、栈、bss、data、符号等部分,分别存储在哪些地方?首先看寄存器1、 寄存器架构参考官方Cortex-M3权威指南下面这个原创 2021-09-17 00:36:51 · 4677 阅读 · 0 评论 -
Linux下用c实现对键盘的监听,实现在Windows中kbhit()函数相同的功能
#include <stdio.h> #include <linux/input.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define DEV_PATH "/dev/input/event1" //difference原创 2021-05-05 17:10:04 · 371 阅读 · 0 评论 -
栈中分配是从高地址往低地址,为什么局部变量的地址却是按定义顺序逐渐增大?从操作系统上进程的地址空间分布以及不同操作系统的不同、以及不同的数据结构来说明这个事情?
先说一个都知道的结论:栈中分配时从高地址往低地址然后我们在Windows下编写一个程序来验证这个结论?#include <stdio.h> void func(int a,int b){ int d; printf("a:%p,b:%p,d:%p\n",&a,&b,&d);}int main(){ int a=0,b=1; printf("real a:%p,b:%p\n",&a,&b); func(a,b);}以上原创 2021-03-23 20:16:23 · 2480 阅读 · 0 评论 -
c语言中char、int以及单引号与双引号的一些理解
char strng[] = "12345"; char x = 1; char x1 = '1'; char x2[] = {1, 2, 3, 4, 5}; char x3[] = {'1', '2', '3', '4', '5'}; printf("x=%d\n \ x1=%d\n \ stng=%c\n \ x2=%d\n \ x3=%d\n", x, x1, *strng,*x2,*x3);说说上面...原创 2021-03-21 16:50:06 · 4250 阅读 · 1 评论 -
如何实现一个打印LOG函数的宏,可以打印所在函数行号等信息
实现这个LOG宏需要了解几个系统宏_ FILE _以字符串形式返回所在文件名称_ func _以字符串形式返回所在函数名称_ LINE _以整数形式返回所在行号每次都用printf来打印信息,参数会一直重复,太过反锁,可以用一个宏来封装printf,只需要写入需要输出还要输出的信息即可,必须要输出的直接封装好,这就是log的目的。同时##的作用是将变量连接在一起,比如int abc =4,def = 5;int abcdef = 0;#define contact(a,b) a##b原创 2020-12-04 15:34:33 · 643 阅读 · 1 评论 -
如何实现一个没有bug的MAX()宏?
一.怎样才算没有bug?需要通过如下测试?1. MAX(2,3)2. 5+MAX(2,3)3. MAX(2,MAX(3,4))4. MAX(2,3>4 ? 3 : 4)5. MAX (a++ , 6) a的初值为7,a的值变为8二.测试技巧和方法第一次写肯定不可能一次就通过,需要不断的测试修改。那怎么进行呢?首先用Linux终端进行编译信息打印可读性好,这里就需要将表达式与结果值一同打印,而平常所用的printf函数打印比较繁琐,可以定义一个宏来简化打印代原创 2020-12-03 23:59:39 · 246 阅读 · 0 评论 -
c语言谷歌测试框架
#include<stdio.h>#include <gtest/gtest.h>int add(int a,int b){ return a+b;}TEST(testfun,add){ EXPECT_EQ(add(1,2),3); EXPECT_EQ(add(2,2),4); EXPECT_EQ(add(3,2),5); EXPECT_EQ(add(1,5),3);}int main(int argc, char co原创 2020-11-19 23:54:53 · 419 阅读 · 0 评论 -
c语言面试题每日一练
目录1.Linux中的常用命令 21.在/tmp/目录下创建test.txt文件,内容为: Hello,World! ,用一个命令写出来。 22.给test.txt文件除所有者之外增加执行权限,最终以数字写出文件的权限。 23.查找linux系统下以config结尾,并备份到/data/backup/目录下 24.创建 test.txt所属的用户为root,组为abc,请将test.txt使拥有者为abc,组为root,写出命令。 25.如何查看文件内容,命令有哪些?查看文件第1行到3行,查看文原创 2020-11-19 20:21:58 · 44585 阅读 · 3 评论 -
用c语言实现汉诺塔问题的递归函数编程
一.汉诺塔问题汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着 6464 片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘,如图所示:现在请试着编写一个程序,对于一个有 nn 个盘子的汉诺塔,列举将这 nn 个盘子从柱子 A 移动到柱子 C 需要的所有移动步骤,每个步骤占一行。例如,将一个盘子从 A 移动到 C,即表示为原创 2020-10-14 17:23:19 · 917 阅读 · 0 评论 -
用C语言编写几种查找质数的方法
一.奇数求余法,列出所有的奇数,然后在判断这些奇数有没有能被整除的小于它自身的奇数,有就不是质数;#include<iostream>using std::cout;using std::endl;int main() { cout << "2" << endl; int digit; int divisor; for (digit = 3; digit <= 15; digit += 2) { for原创 2020-10-14 13:43:00 · 5568 阅读 · 0 评论 -
编写一个程序实现将字符串中的所有“you“替换成“we“
题目:编写一个程序实现将字符串中的所有"you"替换成"we"输入: 输入包含多行数据 每行数据是一个字符串,长度不超过1000 数据以EOF结束输出: 对于输入的每一行,输出替换后的字符串#include<stdio.h>#include<string.h>int main(){ char str[1000]; int i=0,strlong,flag[333],n; //strlong用来储存str的长度,flag用来储存you中u的位置 pr原创 2020-09-25 16:42:48 · 4400 阅读 · 1 评论 -
scanf()函数的两种常见用法,fgets()与feof()用法,读取字符串用法
1.以字符的形式一个一个的字符读取如下:#include<stdlib.h>#include<stdio.h>int main(int argc, char const *argv[]){ char a[100]; int i = 3,m=0; /*i为读取的字符个数,m是将读取到的字符存储在字符串数组中相应的位置 */ while (i--) { printf("请输入字符串");原创 2020-09-25 15:48:47 · 476 阅读 · 0 评论 -
二叉树的性质和C代码实现
一.二叉树的结构和性质二叉树是由许多个节点组成的一种树状的存储数据的结构,每个节点包含了存储的数据和左右两个分支的指针以及一个记录访问该节点次数的计数器。每个节点的左子节点的数据小于该节点,该节点小于右子节点。根据以上二叉树的性质,我们在创建二叉树时可以有一下迭代关系式:创建节点和添加数据:creatnode(value)addnode(struct node *proot,int value)=proot (proot->item = value)proot-原创 2020-09-15 10:49:29 · 150 阅读 · 0 评论 -
vscode在Windows下配置C语言环境,设置三个配置文件
一.需要下载的安装包;1.vscode直接在微软官方下载最新的vscode2.MinGw64里面包含了gcc、gdb等前一个是编译器,后一个是debug的传送链接:MinGW64往下拉点击画圈部分再往下拉点击画圈部分,进行下载下载好后解压里面的文件包含这几个部分;这一步需要将bin文件添加到环境变量:操作如下:右击此电脑,点击属性;点击左边高级系统设置;点击环境变量;双击path;先点击新建,在点击浏览,将刚才解压出来的bin文件添加进去;这一步就完成了;原创 2020-08-31 21:50:26 · 3772 阅读 · 0 评论 -
C中字符指针数组的用法(也即字符串数组),配合malloc,char **p;char *p[n];char (*p)[n];三个的区别
当我们需要输入多个字符串时我们就可以借助指针数组或字符串数组来表示。话不多说直接上程序: char *point[3]={"0","0","0"};/*定义了一个字符指针数组,在这里只是给数组开辟了空间, 也给数组的首地址开辟了一个空间来存放数组的首地址 而这些空间都是用来存放指针的*/ //printf("%p\n%p\n%p\n",point[0],point[1],point[2]); //printf("%p\n%p\n%p\n",&point[0],&poin原创 2020-08-31 14:40:18 · 907 阅读 · 0 评论 -
数组越界,栈与堆问题
一.数组越界的经典案列我们先来看一段代码:#include<stdio.h>int main(){int i;int arr[10];for(i=0;i<=10;i++){arr[i]=0;printf("%d\n",arr[i]);}return 0;}在Linux中的运行结果如下图:这里打印了11个0而且还显示了栈粉碎错误;因为栈是从高地址往低地址扩展,也就是先入的数据在高地址,i定义在arr之前,先被压入栈中在高地址,而数组在栈中是从低地址往高地原创 2020-08-29 23:10:28 · 747 阅读 · 0 评论 -
main函数的返回值和参数问题,以及执行main函数之前都执行了哪些操作?
https://blog.csdn.net/hhhhhyyyyy8/article/details/81908429https://blog.csdn.net/weixin_30550081/article/details/96615303https://blog.csdn.net/weixin_41537785/article/details/81455970https://www.jianshu.com/p/dd425b9dc9db一.main函数的返回值和参数问题C语言main函数返回值:原创 2020-08-29 13:49:25 · 1416 阅读 · 0 评论 -
在使用malloc()函数申请动态数组,重新对多维数组与多重指针之间的关系的思考:数组名就是指针,可以用多重指针和数组的方式访问;顺便对嵌套循环效率的一些解释。
一.先从用malloc()函数申请多维动态函数说起。C语言中用普通的方式定义的数组其大小不能改变。如通过int a[N];定义大小为N的整型数组,其后N的改变不会再改变原来数组大小。但我们可以通过malloc()或calloc()等动态存储分配函数申请分配一块空间,将其返回的所分配单元的起始地址赋给指针,我们就可以利用得到的指针进行和数组一样的操作。因为我们知道普通的数组名其实就是数组的起始地址,相当于一个指针常量。1.定义一个大小为n的整型动态数组,如下: int *a; int n;原创 2020-08-22 00:42:16 · 640 阅读 · 4 评论 -
C/C++中对指针和(char*)强制变换为指针类型的理解(求大小字节序)
首先我们来看一段代码:#include<stdio.h>int main(){ int a=1; char pc = *(char*)(&a); if(pc == 1) printf("第一个字节为1,小端存储\n"); else printf("第一个字节为0,大端存储\n"); return 0;}这段代码中估计很多人对 char pc =* (char*)(&a)不理解。&a是整数型变量a(四个字节)的第一个字节的地址,(char*)原创 2020-08-13 22:46:47 · 1015 阅读 · 3 评论