> 文章列表 > 嵌入式C语言基础知识

嵌入式C语言基础知识

嵌入式C语言基础知识

变量的种类:

  1. 全局变量:定义在函数外部的变量,作用范围是整个程序。
  2. 局部变量:定义在函数内部的变量,作用范围仅限于定义它的函数内部
  3. 静态变量:static,static int a;定义一次就不再消失,会把上一次的值保存起来,下一次直接拿来用。
  4. 静态局部变量:在函数内定义的静态变量,不可以被外部函数调用

运算符和表达式

  1. 数据的类型转换:数据类型自动转换规则:char→int→long→float→double
  2. 逻辑运算:与(&&)、或(||)、非(!)
  3. 位运算:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>)
  • continue;结束本层本次循环,进入下一次循环条件判断。
  • goto无条件转移语句,在结构化设计中,一般不使用该语句,避免程序流程的混乱

函数

  1. 标准库函数头文件<*.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.astu1->name = "张三"; // name1.namecout << 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;
}

共用体

  • 结构体变量所占内存长度:各成员的内存长度之和,每个成员分别占用自己的内存单元
  • 共用体变量:所占内存长度等于最长的成员长度
    共用体的特点:
  1. 同一段内存空间可以存放不同的数据类型,但是在每一瞬间,只有存放其中的一种,只有一个成员起作用(每一瞬间,只有一个成员起作用,其他成员不起作用,即不是同时存在和起作用)。
  2. 共用体中起作用的成员是最后一次存放的成员,存入一个新成员后,原来的成员就失去了作用。
  3. 共用体变量名的地址和各成员的地址相同
  4. 不能再定义共用体变量时进行初始化

枚举

enum 枚举名{枚举值表}

#include <iostream>using namespace std;enum weekday
{sun,mou,tue,web,thu,fri,sat
};int main()
{cout << mou;  // 输出1return 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;
}

文件

  1. C语言把文件当作一个“流”,按字节进行处理
  2. 文件在读写之前必须打开,读写结束必须关闭。
  3. 文件可按字节、字符串、数据块为单位读写

预处理命令

#include <iostream>
#include "test.h"
  • 使用<.h>表示在系统目录中去查找(包含目录是由用户在设置环境时设置的),而不是在源文件目录去查找
  • 使用".h"表示首先在当前的源文件目录中进行查找,如果没有找到才到系统目录中查找

模块化设计

建立两个文件并分别命名,一个命名为initlcd.c,一个命名为initlcd.h
防止头文件重复定义:

#ifndef initlcd_h
#define initlcd_h
.
..
.
#endif

搞笑GIF图片