变量的种类:
- 全局变量:定义在函数外部的变量,作用范围是整个程序。
- 局部变量:定义在函数内部的变量,作用范围仅限于定义它的函数内部
- 静态变量:static,
static int a;
定义一次就不再消失,会把上一次的值保存起来,下一次直接拿来用。 - 静态局部变量:在函数内定义的静态变量,不可以被外部函数调用
运算符和表达式
- 数据的类型转换:数据类型自动转换规则:char→int→long→float→double
- 逻辑运算:与(&&)、或(||)、非(!)
- 位运算:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)
continue;
结束本层本次循环,进入下一次循环条件判断。goto
无条件转移语句,在结构化设计中,一般不使用该语句,避免程序流程的混乱
函数
- 标准库函数头文件
<***.h>
,非标准库函数"***.h"
,后者的检索范围较大
指针
变量的指针:指的是变量的地址,指针就是地址
int i = 10;
int *ip;
ip = &i;
ip加上运算符*后表示访问指针ip内存地址所存储的内容,等价于直接访问i。*表示访问内存地址存储的内容
int x, y;
int *pt = &x;
y = *pt + 5; // 等价于y = x + 5
指针和数组
在嵌入式C语言中,数组名是数组的第0号元素的地址,因此下面两个语句是等价的:
int a[10],*p;
p = &a[0]; // 等价于 p= a;
根据运算规则,a+1为a[1]的地址,a+i就为a[i]的地址。
- *(p+i)和*(p+i)都表示p+i和a+i所指向对象的内容,即a[i]
字符指针
定义字符串常量时,在安排存储区域时,编译器会自动在字符串的末尾加上一个空字符“\0”,表示字符串的结束。定义方法:
char s[] = "hello"; // 如果需要对字符串进行操作,用这种定义方式
char *a = "hello"; // 如果只是存储字符串,用这种定义方式,*a访问的为第一个元素h,a代表字符串首元素的地址
指针数组和数组指针
优先级顺序:() > [] > *
(*p)[n]
根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,即数组的指针,数组指针。
*p[n]
根据优先级,先看[],这是一个数组,再结合*,表示数组的元素是指针类型的,指针的数组,即指针数组,只能存放地址
结构体
// 常用,在定义结构体类型的同时说明结构变量
struct stu
{
int age;
char *name;
} stu1, stu2;
int main(){
stu1.age = 1;
return 0;
}
还可以这样定义一个结构体,省去结构体的名字
struct
{
int age;
char *name;
} stu1, stu2;
结构体数组
struct stu
{
int num;
char *name;
} ;
stu name[2] = {{1, "张三"}, {2, "李四"}};
// 访问结构体成员
name[1].num;
name[2].name;
结构体指针(常用,可以加快程序的执行效率)
- 用指针变量作为函数参数进行传递,由于实参传向形参的只是地址,从而减少了时间和空间上的开销,大大提高了程序的运行效率,使用时注意数组名就是数组元素的首地址。
访问方式:(*结构指针变量).成员名 或 结构指针变量-> 成员名
(*pstu).num; // 等同于 pstu->num
(*pstu)
两侧的()不能少,因为.
的优先级高于*
#include <iostream>
using namespace std;
struct Stu
{
int a;
char *name;
} name1, *stu1;
int main()
{
stu1 = &name1;
stu1->a = 2; // 等价于 name1.a
stu1->name = "张三"; // name1.name
cout << stu1->a << endl;
cout << stu1->name << endl;
return 0;
}
/*分配一块内存区域,输入一个学生的数据*/
#include <iostream>
using namespace std;
struct STU
{
int age;
char *name;
} *stu;
int main()
{
stu = (STU *)malloc(sizeof(STU)); // 给结构体指针分配内存
stu->age = 12;
stu->name = "张三";
cout << stu->age << endl;
cout << stu->name << endl;
// free(stu); // 释放结构体指针内存,释放后该区域不可用,不释放可能会造成程序运行不稳定
return 0;
}
共用体
- 结构体变量所占内存长度:各成员的内存长度之和,每个成员分别占用自己的内存单元
- 共用体变量:所占内存长度等于最长的成员长度
共用体的特点:
- 同一段内存空间可以存放不同的数据类型,但是在每一瞬间,只有存放其中的一种,只有一个成员起作用(每一瞬间,只有一个成员起作用,其他成员不起作用,即不是同时存在和起作用)。
- 共用体中起作用的成员是最后一次存放的成员,存入一个新成员后,原来的成员就失去了作用。
- 共用体变量名的地址和各成员的地址相同
- 不能再定义共用体变量时进行初始化
枚举
enum 枚举名{枚举值表}
#include <iostream>
using namespace std;
enum weekday
{
sun,
mou,
tue,
web,
thu,
fri,
sat
};
int main()
{
cout << mou; // 输出1
return 0;
}
链表
因为链表、文件占用内存较大,所以在单片机中一般不使用。
分配内存空间函数malloc
(类型说明符 *)malloc(size)
功能:在内存的动态存储区中分配一块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。
pc = (char*)malloc(100);
分配内存空间函数calloc
(类型说明符 *)calloc(n,size)
功能:在内存动态存储区域中分配n块长度为“size”字节的连续区域,函数的返回值为该区域的首地址。
calloc
函数与malloc
函数的区别在于,一次可以分配n块区域
释放内存空间函数free
free(void* ptr)
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域
实例
/*分配一块内存区域,输入一个学生的数据*/
#include <iostream>
using namespace std;
struct STU
{
int age;
char *name;
} *stu;
int main()
{
stu = (STU *)malloc(sizeof(STU)); // 给结构体指针分配内存
stu->age = 12;
stu->name = "张三";
cout << stu->age << endl;
cout << stu->name << endl;
free(stu); // 释放结构体指针内存,释放后该区域不可用
return 0;
}
文件
- C语言把文件当作一个“流”,按字节进行处理
- 文件在读写之前必须打开,读写结束必须关闭。
- 文件可按字节、字符串、数据块为单位读写
预处理命令
#include <iostream>
#include "test.h"
- 使用
<.h>
表示在系统目录中去查找(包含目录是由用户在设置环境时设置的),而不是在源文件目录去查找 - 使用
".h"
表示首先在当前的源文件目录中进行查找,如果没有找到才到系统目录中查找
模块化设计
建立两个文件并分别命名,一个命名为initlcd.c
,一个命名为initlcd.h
防止头文件重复定义:
#ifndef initlcd_h
#define initlcd_h
.
..
.
#endif