在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
ZYNQ的SDK是用C语言进行开发的,C语言可以说是当今理工类大学生的必备技能。我本科学C语言时就是对付考试而已,导致现在学ZYNQ是一脸懵逼。现在特开一帖,整理一下C语言的基础知识。
一、定义 1.关键字 char :定义一个8位的变量,就是一个字节。 2.技巧:typedef类型说明符 unsigned char a; //定义一个无符号8位整型变量a //----------------------------------------------------- typedef unsigned char uint8_t; //typedef用法 uint8_t a; //更加明了 实际上很多头文件已经帮我们这样定义好了 typedef signed char int8_t; typedef signed short char int16_t; typedef signed int int32_t; typedef signed _INT64 int64_t; typedef unsigned char uint8_t; typedef unsigned short char uint16_t; typedef unsigned int uint32_t; typedef unsigned _INT64 uint64_t; 3.强制转换 如果结果是浮点型的数据,要保证在计算过程中的变量也是浮点型,如果不是浮点型,可以采用强制类型转换转换成浮点数。 c = (float)a + (float)b; //将a、b强制转换成float型
二、位操作 1.定义
2.技巧 不改变其他位的状况下,对某几位赋值,分两步实现 //①用 & 进行清0操作: //------------------------------------------------------- a &= 0x0F; //对第4-7位清0,第0-3位的值不变 //②用 | 进行赋值操作: //------------------------------------------------------- a |= 0x20; //对第4-7位赋值为2,第0-3位的值不变
三、函数 1.无参数,无返回值 void send123(void) //void不写也行 { printf("%d",1); printf("%d",2); printf("%d",3); } int main(void) { USART1_Init(); 2.有参数,无返回值 void sendx23(uinit8_t x,uinit8_t y) //括号里是形参 { printf("%d",x); printf("%d",y); printf("%d",3); } int main(void) { USART1_Init(); sendx23(1,2); //函数调用,括号里的是实参 while(1) { } } //等价于 ---------------------------------------- int main(void) { USART1_Init(); printf("%d",1); printf("%d",2); printf("%d",3); while(1) { } } 3.有参数,有返回值 uinit8_t sendxyz(uinit8_t x,uinit8_t y,uinit8_t z) { z = x + y; return z; } int main(void) { uint8_t a; USART1_Init(); a = sendxyz(1,2,3); //a = z = 1 + 2; printf('%d',a); while(1) { } }
四、数组 注意,数组名a和&a[0]等价,C语言规定只能逐个引用数组元素,不能一次引用整个数组。 1.一维数组 uint8_t x[3]={0,1,2}; //也可写作 x[] //内部展开可得: //x[0]=0; //x[1]=1; //x[2]=2; 2.二维数组 uint8_t x[3][2] = {{1,1},{1,2},{3,4}}; //5行2列 uint8_t x[3][2] = {1,1,1,2,3,4} //等价写法 3.数组和指针 数组的名字就代表数组的首地址,可将数组的名字赋给和其相同内容的指针,即该指针指向了数组。 int *a,*b,c[10];
五、变量,先定义再使用 1.局部变量(优先级最高) 函数内定义的变量,只能作用于本函数内。 void main() { uint_8 x; } 2.全局变量 函数外定义的变量,可以作用于各个函数中。 uint_8 x; void main() { 3.extern extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里面要注意,对于 extern 申明变量可以多次,但定义只有一次,且不能重复赋值。 ①文件内 //只有b函数才能使用变量x //-------------------------------------- void a() { } uint32_t x; void b() { }
②跨文件 // file1.c //------------------------------- int a; int main { } // file2.c //------------------------------- extern a; int main { } 4.static static定义的值称为静态,生命周期为整个程序周期。 ①局部static,作用域为局部作用域,调用时只会在初次使用时执行初值,后面继续调用的值等于上次结果的值。 //调用多次 int getValue(),flag = 1,1,1,1,1,1,1,1,1...... //----------------------------------------------------------------- int getValue() { int flag=0; //每次都会执行 flag++; return flag; } //调用多次 int getValue(),flag = 1,2,3,4,5,6,7,8,9...... //------------------------------------------------------------------ int getValue() { static int flag=0; //只会执行一次 flag++; return flag; } ②全局static,其作用域为本文件内,其他文件用extern调用是错误的。 // file1.c //------------------------------- int a; static int b; int main { } // file2.c //------------------------------- extern a; //这是对的 extern b; //这是错的!!! int main { }
六、指针 1.指针概念 指针变量a 地址,即0089
指针变量a 值,即0090
指针变量a的值为指针的地址,该地址为另一个变量b的地址
变量b的地址存放着b的内容,即100
2.指针的基本用法 // 1.取地址运算 &,可以得到指针变量本身的地址 // 2.取内容运算 *,可以得到地址数据对应存储单元的内容 int main(void) { uint8_t *a; //对象是地址 uint8_t b; //对象是数据 USART1_Init(); a = &b; //赋值b的地址0090 b = 100; //赋值数据80 printf("%d",&b); //发送的是b的地址:0090 printf("%d", b); //发送的是b的数据:100 printf("%d",&a); //发送的是a的地址:0090 printf("%d", a); //发送的是a的内容即b的地址:0090 printf("%d",*a); //发送的是b的数据:90 while(1) { } } //int *x; 定义一个“指针型的”变量x,*看成是语文层面的对x的修饰词
3.常见混淆式子 *(&a) <=> a //二者等价 &(*a) <=> a //二者等价
七、结构体 结构体是个好东西,在不改变入口参数的情况下,只需要改变结构体的成员变量就可以达到增加函数的路口参数的目的。
1基本概念
①格式:
struct 结构体名 ②也可以在结构体申明的时候定义变量,申明之后再定义: struct 结构体名字 结构体变量列表 ;
struct U_TYPE struct U_TYPE usart1,usart2;
③结构体成员变量的引用方法是: 结构体变量名字.成员名 2.结构体指针 //①定义 //----------------------------------------------------------- struct U_TYPE *usart3;//定义结构体指针变量 usart1; //②引用方法 //----------------------------------------------------------- usart3->BaudRate; //访问 usart3 结构体指针指向的结构体的成员变量 BaudRate *usart3.BaudRate; //二者等价 3.结构体数组 结构体变量作为元素的数组,该数组的每个元素都是一个结构体。 4.结构体和typedef typedef 用于为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。 //①为该结构体定义一个别名GPIO_TypeDef
八、其他知识补充 1.ifdef条件编译 不仅是C语言还是Verilog,都会经常使用这个功能。 // 标识符已被#define定义过则编译程序段1,否则编译程序段2 //=========================================================== #ifdef 标识符 程序段1 #else 程序段2 #endif // #else部分也可以没有 //=========================================================== #ifdef 程序段1 #endif 2.i++和++i int main(void) { uint8_t i; USART1_Init(); i = 5; printf("%d",i++); //等效于 printf("%d",i);即打印结果为5 // i = i+1; while(1) { } } //----------------------------------------------------- int main(void) { uint8_t i; USART1_Init(); i = 5; printf("%d",++i); //等效于 printf("%d",i=i+1);即打印结果为6 // i = i; while(1) { } }
参考资料: [1]瑞生.边学边用攻破C语言.视频教程 [2]康莉, 杨国祥, 项延铁. 零点起飞学C语言[M]. 清华大学出版社, 2013. [3]正点原子STM32教程 |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论