资讯详情

C语言学习笔记

2022.7.26号更新

1、

EXAMPLE_DEVICE_NAME是字符串,默认类型

而P_LEN是unsigned char*正确的方法如下:

2、‘\0和0和0和0的区别

首先对比一下‘’\0和0的区别。有一个共同点,它们都是字符。在c语言中,字符是相应的ASCII存储代码,一个字符占据一个字节。请看第一个ASCII代码,对是0,对应的字符是(Null),其实就是 ‘\即空字符。判断字符串是否结束的标志取决于它是否遇到‘\0’,如果遇到‘\0,表示字符串结束。字符0对应ASCII码是 48,48对应的十六进制数就是0x30。例如,如果你想将8转换为字符8,你可以在句子中这样写 了,“ 8 ‘0’”。这里的8是数字。字符0和数字0的区别:前者是字符常量,后者是整形手术常量,其含义与计算机中的存储方式完全不同。但字符常量 在程序中可以像整数一样参与相关操作。例如:9-3;哈哈,是不是又一村柳暗花明?

接下来我们来比较一下0和0的区别。首先,0是字符串常量,字符串常量是由一对双引号包含的字符序列。例如:“CHINA”,“I LOVE YOU123等都是合法字符串常量。0是字符常量,字符串常量和字符常量不同。1:单引号包括字符常量;双引号包括字符串常量。2:字符常量只能是单个字符;字符串常量可以包含一个或多个字符。

2022.7.23号更新

1、u8 *cmd="AT";

printf("%s",cmd);//可输出AT

2、while(1)

{

break;

}//break最近一个可以退出while循环。

3、&&与&最大的区别:&&是逻辑和,只会返回0和1。

4、

do_crc(&p_data->DEVNO,7);//必须添加&符号

5、

mymalloc函数在malloc.h头文件中有定义,SRAMIN是内部内存池,SRAMEX是外部内存池。

在内存中定义动态堆区,并将堆空间的第一个地址给指针p。一般开辟这段内存是存放临时的数据。

6、

strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,函数返回 str1字符串从 str第一次出现的位置开始到 str1结尾的字符串;否则,返回NULL。

1、sizeof()和strlen()函数有什么区别?

int main() { char *p = "hello"; char q[] = "hello"; char s[10] = "hello"; printf("%d, %d, %d\n", sizeof(p), sizeof(*p), sizeof(q), sizeof(s));

return 0; }

输出结果为:4, 1, 6, 10 p是指针,sizeof(p)得到的是指针占用的字节数,所以sizeof(p)结果为4,p是指向“hello”的指针,*p是“hello第一个字符h,是char类型,sizeof(*p)结果是1,char q[]没有指定数组的大小,根据hello”来确定,“hello包括空字符\0有6个字节,所以sizeof(q)结果为6。char s[10]指定数组大小,包括10个char所以sizeof(s)结果为10。

以下句子是错误的: char q[5] = "hello"; //"hello"是const char[6]类型不能用于初始化char[5]实体类型。

总之,对于指针,sizeof对于数组来说,返回该指针所占的空间通常是4个字节,sizeof返回这个数组中所有元素的总空间大小。char q[]占用空间的大小取决于指向字符串或字符数组的大小,char q[10]占用空间的大小由指定的数组大小决定。

char *p = "hello"; char q[] = "hello"; char s[10] = "hello";

strlen(p), strlen(q), strlen[s]返回结果为5,strlen(p)参数为字符指针(char *),返回字符串的长度不包括‘\0‘。

2、extern的用法

已经在lcd.c下面包含了文件lcdfont.h所以在文件中main函数包含这个头文件会显示重复定义,复定义main还需要使用函数lcdfont.h所以可以有中数组extern这个关键字。

假设b.c下面定义了文件 int b;这句话,所以在a.c如果您想在文件中使用此变量,可以直接使用1)extern int b,但不推荐这种方法;

  1. 也可以在b.h在头文件中声明extern int b,直接调用头部文件。因为B文件可能是你的同事写的,为了更好地协调,你的同事声明B文件的整体变量是外部变量,方便你使用。

在a.c中定义了extern int b;然后当编译时就会生成a.o文件,但不会找到变量B在哪里,而是使用它symbol同时标记b.c文件也会编译,b.c变量定义在文件中b,当两个文件都被编译时,它们将被链接起来,以找到b变量。

3.用宏定义写一个函数

4.输出字符串的格式为%x。

5、sprintf函数的用法

sprintf其功能是将格式化字符串输出到目的字符串中,printf将格式化字符串输出到屏幕上。

但是在keil中不能省略char*类型

6、

7、

8、volatile使用关键词

一般来说,硬件寄存器需要使用volatile外设中的寄存器可以每次访问关键字,而不是Cache。

9、c语言中堆栈指针的位置,C语言及ARM中堆栈指针SP设置的理解与总结

 

 

 

 

10、\r\n和\n\r是不一样的

 

 在printf函数中打印\n\r跟没打印一样,打印\r\n才会回车和换行。

11、printf函数如果将一个浮点型的数据输出%d时,数据就会让人看不懂

12、 

 

 WriteData是一个数组的名称,也就是一个数组的首地址。

13、 

BaseType_t RET;

RET=xTaskCreate(task2,"Task2",100,NULL,1,&Task2_Handle);

上面这种写法就没问题

BaseType_t RET=xTaskCreate(task2,"Task2",100,NULL,1,&Task2_Handle);

这种写法就会报错。

14、定义数据类型是不占用内存空间的

 下面这条语句才会占用内存空间,只有定义了变量才会占用内存空间

15、结构体变量占用的内存空间

 占用8个字节。

 占用104个字节。

占用8个字节

CPU既可以通过偶地址也可以奇地址实现对单个字节的变量进行写,如果是对四个字节的变量进行写就需要从偶地址开始,并且是四个字节为一个整体进行访问(因为是32位处理器,这样访问效率最高)。

 占用8个字节。

 

 

 占用了104个字节

16、变量赋值需要注意的问题

 全局变量就会按单个字节分配char类型的变量。

 

 说明如果是局部变量的话,char类型的变量就会按四字节来分配地址,并且是按地址从高到低分配内存,只有栈才会这样分配。

 

 

17、 

 在main函数的下面定义了一个函数

 

在serial.c文件下面定义了一个函数

 结果打印出来的是main.c。说明函数名称相同的话优先执行本地文件。如果把static关键字去掉的话就会报错了,因为会显示重复定义函数。

 18、结构体多种常见写法

 

 

 19、结构体指针和函数指针

注意:结构体中的classmate变量所占的空间并不清楚,而且会无限套娃,因此不可以使用

 正确做法如下:

 结构体指针

int * add(int a,int b);

这个函数有两种意思,一种是返回值是int *类型,一种是定义了函数指针*add。

为了区分两种意思,应该进行括号分割,当表示返回值是int*类型时,(int * )add(int a,int b);当表示定义了函数指针时,int (* add)(int a,int b);

int (* add)(int a,int b);跟int * add;没有什么差别。int (* add)(int a,int b);并不是一个函数,而是一个变量,这个变量是一个函数指针。

 

 

 

 错误写法如下

 Ifdef即便判断到LCDA为0也会执行,因为有定义。

 执行的是LCD_A()

 

 

 

 

 

20、Typedef

typedef     1      A;是错误的

但是#define  A   1就是正确的

Typedef    int    A;

A i;

就是对的

因为typedef的第二个参数只能是类型,因为typedef本来字面意思就是定义类型的。

 左边的结构体可以由右边两个结构体组合而成。Lcd_operation是前面红框的别名,同理下面的结构体指针类型也是。

21、链表

 

 用一个while(Head)就很巧妙,因为最后一个节点的NEXT是指向NULL。

 

 

 

 

 

 

 

 链表改进

尾部增添成员

 

 

 

 

 删除任意元素(有可能要删除的元素并没有)

 从小到大排列

 通用链表

这种是之前的,采用的是上一个节点的next指向下一个节点的首元素的地址。

 

 改正如下:

 

 

 

 

 它是通过下面这种方法求出偏移地址

 将last->next转化为char*类型进行相减可以保证是按存储单元为字节数进行相减的。

21、通用链表的三种实现方法

 

 

得到了node结构体的地址就得到了person结构体的首地址。

 

 

 

 传入的是node_t的指针,由于这个指针是struct person下的node的成员,因此类型是struct person, 成员是node。

 

 

 双向链表

 

 

 

 

 

 

 

 

 

 22、FreeRTOS链表代码分析

 

 

 

uxNumberOfItems表示有多少个元素

pxIndex指向当前在用的Item,被用来遍历链表。

 

pvOwner是包含Item的结构体

pxContainer:链表

 

 Item初始化

 增加一个元素到尾部

 加入一个新元素必须加入到Index指向的item之前,也就是插入到Index->pxPrevious该item的后面。

 排序item

 

 

 

 

 22、ARM架构与汇编指令

 

23、全局变量的初始化

 

 在bin或者HEX文件里面有代码段和数据段,有值的全局变量就是保存在数据段里的,当烧录到Falsh里面时也是分为代码段和数据段,当程序运行时就会把Flash里面的数据段原封不动的拷贝到RAM中。

 

ZI段是RAM里面的一段内存空间,相当于menset函数,将未初始化或者初始化为0的全局变量的值都初始化为0。

等到有值的全局变量以及初始化为0、未初始化的全局变量都存放好之后就开始调用main函数了。

 Flash里面有代码段和数据段,当程序运行时,数据段会通过类似于mencpy函数的方式重定义到RAM中的Data段,这段空间用于存放有初值的全局变量;同时RAM中也划分出来ZI段,这段空间用于存放初值为0或者无初值的全局变量;接着SP指针会指向RAM中一段空闲的空间用于作为堆栈空间,最后main函数才开始调用。

栈的引用

 

 

标签: 集成电路lcda15c

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台