首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >ZYNQ笔记(0):C语言基础知识复习

ZYNQ笔记(0):C语言基础知识复习

作者头像
FPGA开源工作室
发布于 2020-03-20 01:46:39
发布于 2020-03-20 01:46:39
99400
代码可运行
举报
文章被收录于专栏:FPGA开源工作室FPGA开源工作室
运行总次数:0
代码可运行

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

一、定义

1.关键字

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

2.技巧:typedef类型说明符

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
unsigned char a; //定义一个无符号8位整型变量a
 //----------------------------------------------------- 
typedef unsigned char uint8_t; //typedef用法 
uint8_t a; //更加明了

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.强制转换   

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
c = (float)a + (float)b; //将a、b强制转换成float型

二、位操作

1.定义

2.技巧

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//①用 & 进行清0操作:
//------------------------------------------------------- 
a &= 0x0F; //对第4-7位清0,第0-3位的值不变 
//②用 | 进行赋值操作:
//------------------------------------------------------- 
a |= 0x20; //对第4-7位赋值为2,第0-3位的值不变

三、函数

1.无参数,无返回值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void send123(void) //void不写也行 
{ 
     printf("%d",1); 
    printf("%d",2); 
    printf("%d",3);
 } 


int main(void) 
{ 
    USART1_Init(); 
    send123;    //函数调用 
    while(1) { } 
}
 //等价于 ---------------------------------------- 
int main(void) 
{ 
    USART1_Init(); 
    printf("%d",1); 
    printf("%d",2); 
    printf("%d",3); 
    while(1) 
    { 
    } 
}

2.有参数,无返回值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.有参数,有返回值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.一维数组

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint8_t x[3]={0,1,2}; //也可写作 x[] 
//内部展开可得:
//x[0]=0; 
//x[1]=1;
//x[2]=2; 

2.二维数组

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.数组和指针  

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int *a,*b,c[10]; 
a = c; //将数组c的首地址赋值给指针a 
b = &c[0]; //将数组c的首元素c[0]的地址赋值给指针b 
//指针a、b都指向数组c 
//a = &c; //错误写法!

五、变量,先定义再使用

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void main() 
{  
   uint_8 x; 
}

2.全局变量

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uint_8 x;
 void main() 
 { 
 }

3.extern

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

①文件内

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//只有b函数才能使用变量x 
//-------------------------------------- 
void a()
{
 }
 uint32_t x;
 void b() 
{
 } 
//使用extern 
//-------------------------------------- 
void a() 
{ 
    extern uint32_t x; //表示在某处已经定义过 
} //放到最前面也可以 
uint32_t x; 
void b()
{ 
}

②跨文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// file1.c
 //------------------------------- 
int a; 
int main
 { 
} 
// file2.c
 //------------------------------- 
extern a; 
int main
 {
 }

4.static   

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

①局部static

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//调用多次 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调用是错误的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// file1.c
 //------------------------------- 
int a; 
static int b; 
int main 
{ 
} 
// file2.c 
//------------------------------- 
extern a;   //这是对的 
extern b; //这是错的!!!
int main
 { 
}

六、指针

1.指针概念

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
指针变量a 地址,即0089 
指针变量a 值,即0090 
指针变量a的值为指针的地址,该地址为另一个变量b的地址 
变量b的地址存放着b的内容,即100

2.指针的基本用法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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.常见混淆式子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
*(&a) <=> a //二者等价 
&(*a) <=> a //二者等价 
*a++ //先计算 *a ,再计算 a++ 
*(a++) //先计算 a++ ,再计算 *a
*++a) //先计算 a++,再计算 *a   

七、结构体

结构体是个好东西,在不改变入口参数的情况下,只需要改变结构体的成员变量就可以达到增加函数的路口参数的目的。

1基本概念

①格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct 结构体名 
{ 成员列表; 
}变量名;
//for example 
//----------------------------------- 
struct U_TYPE
 { 
int BaudRate 
int WordLength; 
};usart1,usart2;

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

struct 结构体名字 结构体变量列表 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//for example 
//------------------------------------ 
struct U_TYPE
 {
     int BaudRate; 
    int WordLength; 
}; 
struct U_TYPE usart1,usart2; 

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

结构体变量名字.成员名

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//for example
 //------------------------------------ 
usart1.BaudRate = 1; //对其赋值 
usart1.WordLength = 2; //对其赋值 
//或者这样也行 
//------------------------------------ 
struct U_TYPE
 { 
    int BaudRate;
    int WordLength; 
}usart1={1,2};

2.结构体指针

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//①定义 
//----------------------------------------------------------- 
struct U_TYPE *usart3;//定义结构体指针变量 usart1; 
//②引用方法 
//----------------------------------------------------------- 
usart3->BaudRate; //访问 usart3 结构体指针指向的结构体的成员变量 BaudRate 
*usart3.BaudRate; //二者等价

3.结构体数组   

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

4.结构体和typedef

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//①为该结构体定义一个别名GPIO_TypeDef 
//--------------------------------------------------- 
typedef struct //本名都可以不要 
{
     __IO uint32_t MODER;
     __IO uint32_t OTYPER; 
} GPIO_TypeDef; 
//②通过 GPIO_TypeDef 来定义结构体变量:
//--------------------------------------------------- 
GPIO_TypeDef GPIOA; //常见于函数形参

八、其他知识补充

1.ifdef条件编译

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 标识符已被#define定义过则编译程序段1,否则编译程序段2 
//=========================================================== 
#ifdef 标识符 
程序段1 
#else 程序段2 
#endif 
// #else部分也可以没有 
//=========================================================== 
#ifdef 
程序段1 
#endif 

2.i++和++i

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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教程

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA开源工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【STM32】MDK下的C语言基础
计算机的位是Bit,即数字在计算机中的二进制表示(0和1)。十六进制用于缩写二进制,将二进制从后向前每4位数转换为1位十六进制。
DevFrank
2024/07/24
1510
【STM32】MDK下的C语言基础
【为宏正名】for的妙用你想不到
通过本系列前面两篇文章的学习,我们掌握了宏的基本语法和使用规则,讽刺的是这些所谓的“基本语法和规则”却恰恰是正规C语言教育中所缺失的。本文的内容将建立在前面构筑的基础之上,以for功能的挖掘和封装为契机,手把手的教会你如何正确使用宏来简化日常开发,增强C语言的可读性、降低应用开发的难度、同时还尽可能避免宏对日常代码调试带来的负面影响。
GorgonMeducer 傻孩子
2020/09/11
7400
总结嵌入式C语言知识点
怎么才能做好嵌入式开发?学好C语言吧!今天就来推荐一篇大佬写的嵌入式C语言知识点总结。
嵌入式与Linux那些事
2023/12/18
5780
总结嵌入式C语言知识点
C语言编程基础经典案例
  刚开始学习的时候,会有很多疑惑,例如指针怎么用,结构体跟指针怎么配合,例如函数的参数有什么要求,如何实时更新IO口的数据等。如果重新进行C语言的学习,那么要学很久才能够系统地认识。本文则将比较容易想不起来的知识点进行简单的整理。
用户6754675
2019/12/03
2.1K0
C语言回调函数,提升C技巧必备
“函数返回值类型”表示该指针变量可以指向具有什么返回值类型的函数;“函数参数列表”表示该指针变量可以指向具有什么参数列表的函数。这个参数列表中只需要写函数的参数类型即可。
混说Linux
2023/02/24
1.2K0
C语言回调函数,提升C技巧必备
目前CSDN上最全面的C语言讲解如何用更高层次编写嵌入式C代码
本文首先分析了C语言的陷阱和缺陷,对容易犯错的地方进行归纳整理;分析了编译器语义检查的不足之处并给出防范措施,以Keil MDK编译器为例,介绍了该编译器的特性、对未定义行为的处理以及一些高级应用;在此基础上,介绍了防御性编程的概念,提出了编程过程中就应该防范于未然的多种措施;提出了测试对编写优质嵌入式程序的重要作用以及常用测试方法;最后,本文试图以更高的层次看待编程,讨论一些通用的编程思想。
苏州程序大白
2021/08/13
2.5K0
目前CSDN上最全面的C语言讲解如何用更高层次编写嵌入式C代码
(七)STM32基础——C语言知识复习
        这个地方有一些和C语言是不一样的,就是关键字的定义不同,稍微注意一下就可以了。
小点点
2022/12/12
2870
(七)STM32基础——C语言知识复习
stm32_DMA采集一个AD数据_并通过DMA向串口发送
这是以前学32的时候写的,那时候学了32之后感觉32真是太强大了,比51强的没影。关于dma网上有许多的资料,关于dma采集ad网上也有很多。亲们搜搜,这里只贴代码了,其实我也想详详细细地叙述一番,但
杨奉武
2018/04/18
1.2K0
stm32_DMA采集一个AD数据_并通过DMA向串口发送
c语言基础知识菜鸟_c语言入门基础100题
C中每个变量都有其特定类型,类决定了变量存储的大小和布局(指定范围内的值都可以存储到内存中,运算符作用变量上)
全栈程序员站长
2022/09/21
1K0
【STM32H7教程】第29章 STM32H7的USART串口基础知识和HAL库API
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第29章 STM32H7的USART串口基础知识和H
Simon223
2019/07/19
2.3K0
【STM32H7教程】第29章       STM32H7的USART串口基础知识和HAL库API
嵌入式 C 语言(中)
volatile原意是“易变的”,在嵌入式环境中用volatile关键字声明的变量,在每次对其值进行引用的时候都会从原始地址取值。由于该值“易变”的特性所以,针对其的任何赋值或者获取值操作都会被执行(而不会被优化)。由于这个特性,所以该关键字在嵌入式编译环境中经常用来消除编译器的优化,可以分为以下三种情景:
韦东山
2022/05/05
1.6K0
嵌入式 C 语言(中)
学习C语言基础知识 | 实践篇
C语言的数据类型 C语言的数据类型 (1)输入输出 #include <stdio.h> int main(int args, const char *argv){ //单纯字符串输出 puts("hello world"); //格式化输出 printf("hello %s\n","alicfeng"); //输入 char username[10]; int age; gets(username);//很危险的做法 推荐不使
AlicFeng
2018/06/08
8110
STM32通信串口RS232
RS232是美国电子工业协会(Electronic Industries Association,EIA)于1962年发布的串行通信接口标准,其中RS为英文“Recomend Standard”的缩写,中文翻译为“推荐标准”,232为标识号。该标准对串行通信的物理接口及逻辑电平都做了规定,其输出的电平称为RS232电平。
韦东山
2022/05/05
1.2K0
STM32通信串口RS232
C语言基础总结
我学习的第一门编程语言是Java,所以之前一直没有系统学习过C语言。这篇文章主要就是我学习过程的一个总结,方便以后复习查看。
害恶细君
2024/09/16
3090
C语言基础总结
C语言基础(4)
函数的作用是:定义一个函数,在进行多次复杂计算时可以直接引用过来,避免函数的复杂冗长,节省内存和时间。简单来说就是:简化代码,代码复用。下面举一例子:
see.
2024/06/04
1710
C语言基础(4)
环形队列
 写完这篇文章想着以后尽量(应该说一定)使用现在正在使用的LPC系列的单片机写程序,其实内心感觉还是LPC做的相当完善,,,,,配置上没有32那么的繁琐.... 关于串口发送数据,自己以前呢是这样 void Usart_Out_Char(unsigned char *c,uint32_t cnt) { while(cnt--) { USART_SendData(USART1, *c++); while(USART_GetFlagStatus(USART1, USART_FLA
杨奉武
2018/04/18
1.4K0
环形队列
C语言的面向对象编程
面向对象编程是一种思想,并非一定要用哪种语言去实现,c语言也可以实现面向对象编程。通过结构体和指针就可以实现。
用户9736681
2023/02/20
1.7K0
C语言的面向对象编程
基于STM32设计的出租车计费系统
在城市交通中,出租车是一种常见的交通工具。为了方便乘客和司机之间的交易,出租车计费系统被广泛应用于出租车行业。系统能够自动计算乘客的费用,提供准确、方便的计费服务,并且能够记录乘客的行驶数据,方便后续查询和管理。
DS小龙哥
2023/08/09
5220
基于STM32设计的出租车计费系统
基于单片机设计的智慧农业大棚检测系统
本项目基于单片机设计一个智慧农业大棚检测系统,以提供实时监测和管理大棚环境的关键参数。系统支持环境温度、湿度检测,光照强度检测,并能根据预设的阀值进行报警提示。为了实现数据的显示和管理,该系统还利用Qt开发了一款对应的Android手机APP,通过蓝牙传输模块将单片机采集到的数据传递到手机APP上进行显示和管理。
DS小龙哥
2024/01/09
1.5K0
基于单片机设计的智慧农业大棚检测系统
初识C语言(3)
 C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。
用户10923087
2024/01/23
1680
初识C语言(3)
相关推荐
【STM32】MDK下的C语言基础
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档