单片机(C语言)代码基础入门

头文件

<头文件>和"头文件"

  1. #include <头文件>  :     编译器只会从系统配置的库环境中去寻找头文件,不会搜索当前文件夹。        通常用于引用标准库头文件。
  2. #include "头文件"  :     编译器会先从当前文件夹中寻找头文件,如果找不到则到系统默认库环境中去寻找。     一般用于引用用户自己定义使用的头文件。

变量的定义\宏定义

#define

#define定义的标识符常量

宏定义防止使用时错误用小括号包含。

#define 标识符        常量值                    //常量
#define TXBUFF_SIZE   (128)             //发送缓冲大小
//将宏定义做如下修改即可避免溢出问题
#define VOLT_RATE     ((long)1000)     /*比例系数,强整成 long*/


// 函数
#define     ADD(a,b)        (a+b)
#define     MAX( x, y )     ( ((x) > (y)) ? (x) : (y) )            //最值
#define     WORD_LO(xxx)    ((int_8) ((int_16)(xxx) & 255))        //取低位

enum

枚举常量

enum DAY
{
      MON = 0, TUE, WED, THU, FRI, SAT, SUN
};

 对于没有指定值的枚举元素,其值为前一元素加 1。

关键字

volatile

volatile 是一个关键字,用于告诉编译器,变量的值可能会在程序执行期间被意外地改变,因此编译器不应该对该变量进行优化。

static

静态(static)

static修饰局部变量改变了变量的生命周期,让静态局部变量超出了作用域后依然存在,直到程序结束时,生命周期才结束。

一个函数被static修饰,这个函数就只能在本源文件内使用,不能在其他源文件内使用。

静态全局变量在声明它的文件之外是不可见的,仅在从定义该变量的开始位置到文件结尾可见。

局部变量的值在函数调用结束之后不会消失,仍然保留函数调用结束的值。即它所在的存储单元不释放。        即静态局部变量存储在静态存储区,当静态局部变量离开作用域后,并没有被销毁。当该函数再次被调用的时候,该变量的值为上次函数调用结束时的值。

extern

外部(extern)

const

const修饰的变量不能修改。

用const修饰过的局部变量只是有了「静态特性」,并没有说它变成了「静态变量」。

让逻辑错误在编译期被发现。(无意修改 str[4]='x' 值时,可以编译报错)

struct 

结构体

_Bool

布尔类型        bool

typedef 

声明定义

typedef struct 
{
 float temperature; //温度
 char  humidity;    //湿度
 char  alcohol;    //酒精浓度
 int   illumination;//光照强度
 char  CO;          //一氧化碳浓度
} sensor;

sensor sen;

void

void的字面意思是“无类型”,void *则为“无类型指针”,void *可以指向任何类型的数据。

void真正发挥的作用在于:

(1) 对函数返回的限定;

(2) 对函数参数的限定。

void关键字的使用规则

(1) 如果函数没有返回值,则应声明为void类型;
(2) 如果函数无参数,则应声明其参数为void;
(3) 如果函数的参数可以是任意类型指针,则应声明为其参数为void *;
(4) Void不能代表一个真实的变量;

void * 的使用规则

void *指向的数据类型未定义,
将void *赋值给其它值时需强制类型转换(例1),
但任何类型的指针都可以直接赋(例2)

// 例 1
	void *arg;
	int i;
	i=(int *)arg;
// 例 2
    void *p1;
	int *p2;
	p1 = p2;

 -小心使用void *(void指针)

不能对void指针进行算术操作。

void * pvoid;
Pvoid++;    //非法
Pvoid--;    //非法
int pint;
Pint++;    //正确

注:在GNU编译器中,它指定void *的算算术操作于char *算术操作一致,因此在GNU编译器中viod *类型的变量算术运算是正确的。

– 如果函数的参数可以是任意类型指针,则应声明为void *
如我们常用到的:

void * menset(void * buffer,int c,size_t num);
void *mencpy(void *dest,const void *src,size_t len);

将void * 指针缓存区的数据内容存入(数组)内存;

#include <stdio.h>
void *	payload;
char	*rxbuf;
int main()
{
	char a[5] = { 0x01,0x02,0x03,0x04,0x05 };
	payload = &a;
	printf("a[0]		=%x\n", a[0]);
	printf("&a			=%x\n", &a);
	printf("*a			=%x\n", *a);
	printf("&rxbuf		=%x\n", &rxbuf);

	rxbuf = (char *)payload;

	printf("&rxbuf		=%x\n", &rxbuf);
	printf("rxbuf[1]	=%x\n", rxbuf[1]);
	printf("rxbuf[2]	=%x\n", rxbuf[2]);
}

功能函数

 常用标准库头文件

stdio.h                //输入输出

stdlib.h                //内存管理,生成随机数

math.h              //数学运算

stdbool.h              //关键字_Bool可以表示布尔类型。

string.h             

//字符串操作

void *memset(void *s, int ch, size_t n);

函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。

知识点

指针

从根本上看,指针是是一个值为内存地址的变量(或数据对象)。指针与底层硬件联系紧密,使用指针可操作数据的地址,实现数据的间接访问。

指针的操作

  • 若已定义:
            int a;        //定义一个int型的数据           
            int *p;        //定义一个指向int型数据的指针
  • 则对指针p有如下操作方式:
  • & 取地址
            如果&运算符左右都有变量,那么这个符号就代表位运算&;
            如果&运算符只有右边是变量,那个就代表取地址的意思
    * 取内容
            如果*运算符左右都有变量,那么这个符号就代表乘法运算符;
            int *中的*只是一个标识,一个代号
            如果* 只有后面有变量,而前面没有数据类型,那就是取内容,就是解引用的意思

    数组与指针
    数组是一些相同数据类型的变量组成的集合,其数组名即为指向该数据类型的指针。数组的定义等效于 申请内存、定义指针和初始化

    例如:        char c[] = {0x33, 0x34, 0x35};
    等效于:     申请内存
                        定义char *c = 0x4000;
                        初始化数组数据

    利用下标引用数据也等效于指针取内容

    c[0];        等效于:*c;
    c[1];        等效于:*c+1;
    c[2];        等效于:*c+2;

    (uint8_t *) 表示强制转换成uint8_t类型的指针。

    uint8应该是无符号8位二进制整型,其实就是unsigned char类型。

    将变量t类型强制转换为uint8 *类型,也就是转换成指向uint8类型变量的指针变量。

    字符

    将字符串转换为整数

    atoi(s1):                                //        atoi(“100”):        转化为整数100  

    作者:蛋蛋的学习记录

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机(C语言)代码基础入门

    发表回复