ZYNQ的SDK是用C语言进行开发的,C语言可以说是当今理工类大学生的必备技能。我本科学C语言时就是对付考试而已,导致现在学ZYNQ是一脸懵逼。现在特开一帖,整理一下C语言的基础知识。

一、定义

1.关键字

  1. char     :定义一个8位的变量,就是一个字节。
    short int :定义一个16位的变量,就是两个直接
  2. int      :定义一个32位(一般情况下)的变量,就是四个字节。
  3. float     :定义一个精度为6位小数点的浮点型小数,超过精度的数据会有偏差,本身即有符号型。
  4. double    :定义一个精度为15位的小数点的浮点型小数,超过精度的数据会有偏差,本身即有符号型。
  5. unsigned   :加在前面四个关键字前面,表示无符号的数据,就是“只有正数”的意思。
  6. signed   :加在前面四个关键词前面,表示有符号的数据,就是“有正负数”的意思。
  7. signed char :等效于char ,因为signed 可以省略。也就是,如果不定义unsigend,那肯定是有符号的。
  8.  
  9. #define    :宏定义

2.技巧:typedef类型说明符

  1. unsigned char a; //定义一个无符号8位整型变量a
  2. //-----------------------------------------------------
  3. typedef unsigned char uint8_t; //typedef用法
  4. uint8_t a; //更加明了

实际上很多头文件已经帮我们这样定义好了

  1. typedef signed char int8_t;
  2. typedef signed short char int16_t;
  3. typedef signed int int32_t;
  4. typedef signed _INT64 int64_t;
  5.  
  6. typedef unsigned char uint8_t;
  7. typedef unsigned short char uint16_t;
  8. typedef unsigned int uint32_t;
  9. typedef unsigned _INT64 uint64_t;
    .
    .
    .

3.强制转换

  如果结果是浮点型的数据,要保证在计算过程中的变量也是浮点型,如果不是浮点型,可以采用强制类型转换转换成浮点数。

  1. c = (float)a + (float)b; //将a、b强制转换成float型

二、位操作

1.定义

2.技巧

不改变其他位的状况下,对某几位赋值,分两步实现

  1. //①用 & 进行清0操作:
  2. //-------------------------------------------------------
  3. a &= 0x0F; //对第4-7位清0,第0-3位的值不变
  4.  
  5. //②用 | 进行赋值操作:
  6. //-------------------------------------------------------
  7. a |= 0x20; //对第4-7位赋值为2,第0-3位的值不变

三、函数

1.无参数,无返回值

  1. void send123(void) //void不写也行
  2. {
  3. printf("%d",);
  4. printf("%d",);
  5. printf("%d",);
  6. }
  7.  
  8. int main(void)
  9. {
  10. USART1_Init();
  11. send123;    //函数调用
  12. while()
  13. {
  14. }
  15. }
  16.  
  17. //等价于 ----------------------------------------
  18.  
  19. int main(void)
  20. {
  21. USART1_Init();
  22. printf("%d",);
  23. printf("%d",);
  24. printf("%d",);
  25. while()
  26. {
  27. }
  28. }

2.有参数,无返回值

  1. void sendx23(uinit8_t xuinit8_t y) //括号里是形参
  2. {
  3. printf("%d",x);
  4. printf("%d",y);
  5. printf("%d",);
  6. }
  7.  
  8. int main(void)
  9. {
  10. USART1_Init();
  11.  
  12. sendx23(1,2); //函数调用,括号里的是实参
  13.  
  14. while()
  15. {
  16. }
  17. }
  18.  
  19. //等价于 ----------------------------------------
  20.  
  21. int main(void)
  22. {
  23. USART1_Init();
  24.  
  25. printf("%d",);
  26. printf("%d",);
  27. printf("%d",);
  28.  
  29. while()
  30. {
  31. }
  32. }

3.有参数,有返回值

  1. uinit8_t sendxyz(uinit8_t xuinit8_t yuinit8_t z)
  2. {
  3. z = x + y;
  4. return z;
  5. }
  6.  
  7. int main(void)
  8. {
  9. uint8_t a;
  10. USART1_Init();
  11.  
  12. a = sendxyz(,,); //a = z = 1 + 2;
  13. printf('%d',a);
  14.  
  15. while()
  16. {
  17. }
  18. }

四、数组

  注意,数组名a和&a[0]等价,C语言规定只能逐个引用数组元素,不能一次引用整个数组。

1.一维数组

  1. uint8_t x[]={,,}; //也可写作 x[]
  2. //内部展开可得:
  3. //x[0]=0;
  4. //x[1]=1;
  5. //x[2]=2;

2.二维数组

  1. uint8_t x[][] = {{,},{,},{,}}; //5行2列
  2. uint8_t x[][] = {,,,,,}      //等价写法

3.数组和指针

  数组的名字就代表数组的首地址,可将数组的名字赋给和其相同内容的指针,即该指针指向了数组。

  1. int *a,*b,c[];
  2. a = c; //将数组c的首地址赋值给指针a
  3. b = &c[]; //将数组c的首元素c[0]的地址赋值给指针b
  4.  
  5. //指针a、b都指向数组c
  6.  
  7. //a = &c; //错误写法!

五、变量,先定义再使用

1.局部变量(优先级最高)

  函数内定义的变量,只能作用于本函数内。

  1. void main()
  2. {
  3. uint_8 x;
  4. }

2.全局变量

  函数外定义的变量,可以作用于各个函数中。

  1. uint_8 x;
  2.  
  3. void main()
  4. {
    }

3.extern

  extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里面要注意,对于 extern 申明变量可以多次,但定义只有一次,且不能重复赋值。

①文件内

  1. //只有b函数才能使用变量x
  2. //--------------------------------------
  3. void a()
  4. {
  5. }
  6.  
  7. uint32_t x;
  8.  
  9. void b()
  10. {
  11. }
  12.  
  13. //使用extern
  14. //--------------------------------------
  15. void a()
  16. {
    extern uint32_t x; //表示在某处已经定义过
    } //放到最前面也可以
  1. uint32_t x;
    void b()
    {
    }

②跨文件

  1. // file1.c
  2. //-------------------------------
  3. int a;
  4.  
  5. int main
  6. {
  7. }
  8.  
  9. // file2.c
  10. //-------------------------------
  11. extern a;
  12.  
  13. int main
  14. {
  15. }

4.static

  static定义的值称为静态,生命周期为整个程序周期。

①局部static,作用域为局部作用域,调用时只会在初次使用时执行初值,后面继续调用的值等于上次结果的值。

  1. //调用多次 int getValue(),flag = 1,1,1,1,1,1,1,1,1......
  2. //-----------------------------------------------------------------
  3. int getValue()
  4. {
  5. int flag=0;       //每次都会执行
  6. flag++;
  7. return flag;
  8. }
  9.  
  10. //调用多次 int getValue(),flag = 1,2,3,4,5,6,7,8,9......
  11. //------------------------------------------------------------------
  12. int getValue()
  13. {
  14. static int flag=0; //只会执行一次
  15. flag++;
  16. return flag;
  17. }

②全局static,其作用域为本文件内,其他文件用extern调用是错误的。

  1. // file1.c
  2. //-------------------------------
  3. int a;
  4. static int b;
  5.  
  6. int main
  7. {
  8. }
  9.  
  10. // file2.c
  11. //-------------------------------
  12. extern a;   //这是对的
  13. extern b; //这是错的!!!
  14. int main
  15. {
  16. }

六、指针

1.指针概念

  1. 指针变量a 地址,即0089
  2. 指针变量a 值,即0090
  3.  
  4. 指针变量a的值为指针的地址,该地址为另一个变量b的地址
  5. 变量b的地址存放着b的内容,即100

 2.指针的基本用法

  1. // 1.取地址运算 &,可以得到指针变量本身的地址
  2. // 2.取内容运算 *,可以得到地址数据对应存储单元的内容
  3.  
  4. int main(void)
  5. {
  6. uint8_t *a; //对象是地址
  7. uint8_t b; //对象是数据
  8.  
  9. USART1_Init();
  10.  
  11. a = &b; //赋值b的地址0090
  12. b = ; //赋值数据80
  13.  
  14. printf("%d",&b); //发送的是b的地址:0090
  15. printf("%d", b); //发送的是b的数据:100
  16. printf("%d",&a); //发送的是a的地址:0090
  17. printf("%d", a); //发送的是a的内容即b的地址:0090
  18. printf("%d",*a); //发送的是b的数据:90
  19.  
  20. while()
  21. {
  22. }
  23. }
  1. //int *x; 定义一个“指针型的”变量x,*看成是语文层面的对x的修饰词

3.常见混淆式子

  1. *(&a) <=> a //二者等价
  2. &(*a) <=> a //二者等价
  3.  
  4. *a++ //先计算 *a ,再计算 a++
    *(a++) //先计算 a++ ,再计算 *a
    *(++a //先计算 a++,再计算 *a

七、结构体

  结构体是个好东西,在不改变入口参数的情况下,只需要改变结构体的成员变量就可以达到增加函数的路口参数的目的。
1基本概念
①格式:
  1. struct 结构体名
    {
  2. 成员列表;
    }变量名;
  3. //for example
    //-----------------------------------
    struct U_TYPE
    {
  4. int BaudRate
  5. int WordLength;
  6. };usart1,usart2;

②也可以在结构体申明的时候定义变量,申明之后再定义:

  1. struct 结构体名字 结构体变量列表 ;
  2. //for example
    //------------------------------------
  1. struct U_TYPE
    {
  2. int BaudRate
  3. int WordLength;
  4. };
  1. struct U_TYPE usart1usart2;

③结构体成员变量的引用方法是:

  1. 结构体变量名字.成员名
  2. //for example
    //------------------------------------
  3. usart1.BaudRate = 1; //对其赋值
    usart1.WordLength = 2; //对其赋值
  4.  
  5. //或者这样也行
    //------------------------------------
    struct U_TYPE
    {
    int BaudRate
    int WordLength;
    }usart1={1,2};

2.结构体指针 

  1. //①定义
  2. //-----------------------------------------------------------
  3. struct U_TYPE *usart3//定义结构体指针变量 usart1;
  4.  
  5. //②引用方法
  6. //-----------------------------------------------------------
  7. usart3->BaudRate; //访问 usart3 结构体指针指向的结构体的成员变量 BaudRate
  8. *usart3.BaudRate; //二者等价

 3.结构体数组

  结构体变量作为元素的数组,该数组的每个元素都是一个结构体。

 4.结构体和typedef

  typedef 用于为现有类型创建一个新的名字,或称为类型别名,用来简化变量的定义。

  1. //①为该结构体定义一个别名GPIO_TypeDef
    //---------------------------------------------------
  2. typedef struct //本名都可以不要
  3. {
  4. __IO uint32_t MODER;
  5. __IO uint32_t OTYPER;
  6. } GPIO_TypeDef;
  7.  
  8. //②通过 GPIO_TypeDef 来定义结构体变量:
    //---------------------------------------------------
  9. GPIO_TypeDef GPIOA; //常见于函数形参
 

八、其他知识补充

1.ifdef条件编译

不仅是C语言还是Verilog,都会经常使用这个功能。

  1. // 标识符已被#define定义过则编译程序段1,否则编译程序段2
  2. //===========================================================
  3. #ifdef 标识符
  4. 程序段1
  5. #else
  6. 程序段2
  7. #endif
  8.  
  9. // #else部分也可以没有
  10. //===========================================================
  11. #ifdef
  12. 程序段1
  13. #endif

2.i++和++i

  1. int main(void)
  2. {
  3. uint8_t i;
  4. USART1_Init();
  5.  
  6. i = ;
  7. printf("%d",i++); //等效于 printf("%d",i);即打印结果为5
  8. // i = i+1;
  9. while()
  10. {
  11. }
  12. }
  13.  
  14. //-----------------------------------------------------
  15.  
  16. int main(void)
  17. {
  18. uint8_t i;
  19. USART1_Init();
  20.  
  21. i = ;
  22. printf("%d",++i); //等效于 printf("%d",i=i+1);即打印结果为6
  23. // i = i;
  24. while()
  25. {
  26. }
  27. }

参考资料:

[1]瑞生.边学边用攻破C语言.视频教程

[2]康莉, 杨国祥, 项延铁. 零点起飞学C语言[M]. 清华大学出版社, 2013.

[3]正点原子STM32教程

ZYNQ笔记(0):C语言基础知识复习的更多相关文章

  1. 复习笔记——1. C语言基础知识回顾

    1. 数据类型 1.1 基本数据类型 整型:int, long,unsigned int,unsigned long,long long-- 字符型:char 浮点型:float, double-- ...

  2. C语言程序设计做题笔记之C语言基础知识(下)

    C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...

  3. C语言程序设计做题笔记之C语言基础知识(上)

    C语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行事.并且C是相当灵活的,用于执行计算机程序能完成的几乎 ...

  4. linux c 笔记-3 c语言基础知识

    关键字 数据类型: 简单(7):int long short float double char enum 复杂(2):struct union 类型修饰符(8):auto unsigned sign ...

  5. ios开发学习笔记001-C语言基础知识

    先来学习一下C语言基础知识,总结如下: 在xcode下编写代码. 1.编写代码 2.编译:cc –c 文件名.c 编译成功会生成一个 .o的目标文件 3.链接:把目标文件.o和系统自带的库合并在一起, ...

  6. OC语言基础知识

    OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...

  7. 李洪强iOS开发之OC语言基础知识

    OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能 ...

  8. Golang 入门系列(三)Go语言基础知识汇总

    前面已经了 Go 环境的配置和初学Go时,容易遇到的坑,大家可以请查看前面的文章 https://www.cnblogs.com/zhangweizhong/category/1275863.html ...

  9. Spring Cloud微服务实战阅读笔记(一) 基础知识

    本文系<Spring Cloud微服务实战>作者:翟永超,一书的阅读笔记. 一:基础知识   1:什么是微服务架构     是一种架构设计风格,主旨是将一个原本独立的系统拆分成多个小型服务 ...

随机推荐

  1. 51: Luogu 2485 模板

    $des$ 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最小非负整数x: 3.给定y.z.p,计算满足y^x ≡z(mod p)的最小非负 ...

  2. 【LG2154】[SDOI2009]虔诚的墓主人

    [LG2154][SDOI2009]虔诚的墓主人 题面 洛谷 题解 如果您没有看懂题,请反复阅读题面及样例 可以发现,对于某一个点,它的答案就是上下左右几个组合数乘起来. 这样直接做复杂度显然爆炸,考 ...

  3. .NET项目发布到本地IIS完整流程(VS2015)

    概要: 一.安装IIS功能 二.建立发布网站 三.发布应用程序 四.发布后各种问题的解决. [可先看概要四,可避免很多坑] 具体操作: 一.安装IIS功能 选择必要的功能进行安装,重启有效. 二.建立 ...

  4. rancher2基础环境配置

    一.主机配置 1.配置要求 参考节点要求 2.主机名配置 因为K8S的规定,主机名只支持包含 - 和 .(中横线和点)两种特殊符号,并且主机名不能出现重复. 3.Hosts 配置每台主机的hosts( ...

  5. eclipse debug调试 class文件 Source not found.

      1.情景展示 明明有class文件,为什么提示没有? 2.原因分析 这是eclipse与myeclipse的不同之处,myeclipse会自动加载运行时所需的的class文件,而eclipse则需 ...

  6. Zabbix实战-简易教程--中间件RabbitMQ监控

    一.环境 zabbix版本:3.0 二.脚本说明 .├── rabbitmq.template.xml   模板文件├── scripts  │   └── rabbitmq│   ├── api.p ...

  7. vue----子组件引用vux popup mask遮罩在最上层解决办法 z-index问题

    在一个页面的子组件中引用vux的popup组件时,出现mask遮罩在最上层的问题,百度了一下发现有两种解决办法,现提供第三种. popup在子组件引用时,vux将vux-popup-mask默认添加到 ...

  8. Spring Boot-JPA常用注解

  9. Mesa: GeoReplicated, Near RealTime, Scalable Data Warehousing

    Mesa的定义并没有反映出他的特点,因为分布式,副本,高可用,他都是依赖google的其他基础设施完成的 他最大的特点是,和传统数仓比,可以做到near real-time的返回聚合的查询结果 算入实 ...

  10. IDEA 如何导出 todo 列表

    众所周知,IDEA 可以直接查看所有的 todo 列表, 快捷键是 Alt + 6 然后右键文件夹,选择[Expand All],展开所有目录 再然后,先选中最上边的文件,单击, 再选中最后一个文件, ...