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

一、定义

1.关键字

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

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",);
printf("%d",);
printf("%d",);
} int main(void)
{
USART1_Init();
send123;    //函数调用
while()
{
}
} //等价于 ---------------------------------------- int main(void)
{
USART1_Init();
printf("%d",);
printf("%d",);
printf("%d",);
while()
{
}
}

2.有参数,无返回值

void sendx23(uinit8_t x,uinit8_t y) //括号里是形参
{
printf("%d",x);
printf("%d",y);
printf("%d",);
} int main(void)
{
USART1_Init(); sendx23(1,2); //函数调用,括号里的是实参 while()
{
}
} //等价于 ---------------------------------------- int main(void)
{
USART1_Init(); printf("%d",);
printf("%d",);
printf("%d",); while()
{
}
}

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(,,); //a = z = 1 + 2;
printf('%d',a); while()
{
}
}

四、数组

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

1.一维数组

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

2.二维数组

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

3.数组和指针

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

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

五、变量,先定义再使用

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()
{
} //使用extern
//--------------------------------------
void a()
{
extern uint32_t x; //表示在某处已经定义过
} //放到最前面也可以
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 = ; //赋值数据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()
{
}
}
//int *x; 定义一个“指针型的”变量x,*看成是语文层面的对x的修饰词

3.常见混淆式子

*(&a) <=> a    //二者等价
&(*a) <=> a //二者等价 *a++ //先计算 *a ,再计算 a++
*(a++) //先计算 a++ ,再计算 *a
*(++a) //先计算 a++,再计算 *a

七、结构体

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

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

struct 结构体名字 结构体变量列表 ;
//for example
//------------------------------------
struct U_TYPE
{
int BaudRate
int WordLength;
};
struct U_TYPE usart1,usart2;

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

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

2.结构体指针 

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

 3.结构体数组

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

 4.结构体和typedef

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

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

八、其他知识补充

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 = ;
printf("%d",i++); //等效于 printf("%d",i);即打印结果为5
// i = i+1;
while()
{
}
} //----------------------------------------------------- int main(void)
{
uint8_t i;
USART1_Init(); i = ;
printf("%d",++i); //等效于 printf("%d",i=i+1);即打印结果为6
// i = i;
while()
{
}
}

参考资料:

[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. LINUX下的gdb调试方法

    首先对目标文件进行编译 例如: gcc test.c -o test 这时会生成一个文件test,然后我们就可以对test进行调试了 示例: gdb test 好了以后是设定断点 示例: break ...

  2. P5055 【模板】可持久化文艺平衡树 可持久化fhqtreap

    P5055 [模板]可持久化文艺平衡树 链接 luogu 思路 可持久化fhq-treap套一套就行了,pushdown和split都要可持久化,但merge不用可持久.以前以为很难一直没看,就是个板 ...

  3. 第五届新疆ACM H-虚无的后缀

    来源 第五届新疆省ACM-ICPC程序设计竞赛nowcoder重现赛 H-虚无的后缀 思路1 好菜哦. 首先后缀零的个数最多,我们只需要考虑他的质因子2和5的个数就行了(存为a,b). 因为其他因子对 ...

  4. luogu P1724 东风谷早苗

    二次联通门 : luogu P1724 东风谷早苗 /* luogu P1724 东风谷早苗 模拟即可 手抖 Y-- 打成 Y++ WA了两发.. */ #include <cstring> ...

  5. pytesseract.pytesseract.TesseractError: (1, 'Error opening data file /usr/local/share/tessdata/chi_sim.traineddata Please make sure the TESSDATA_PREFIX environment variable is set to your "tessdata"

    pytesseract.pytesseract.TesseractError: (1, 'Error opening data file /usr/local/share/tessdata/chi_s ...

  6. vi 调到第一行和最后一行

    gg 跳到文件第一行Shift + g 跳到文件最后一行 chmod 777 abc.txt

  7. pyqt(day2)

    一.安装python 二.安装pyqt5 pip install pyqt5 三.安装pycharm 四.第一个pyqt程序 import sys from PyQt5.QtWidgets impor ...

  8. Refused to execute script from '...' because its MIME type ('') is not executable, and strict MIME type checking is enabled.

    写在前面 部署项目到weblogic上启动首页访问空白, 浏览器控制台报如题错误. web.xml中把响应头添加防止攻击的报文过滤器禁用就行了(仅仅是为了启动), 以下为转载内容, 可以根据需要自行测 ...

  9. 前端知识点回顾之重点篇——CSS中flex布局

    flex布局 来源: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool 采用 Flex 布局的元素 ...

  10. Windows上的那些效率神器,让你快到飞起

    转自:https://zhuanlan.zhihu.com/p/41771626 本文为Windows上有哪些让你效率倍增的软件和小技巧系列第二篇,上一篇请点击蓝字查看:打造高逼格PC,让你的电脑好用 ...