(1)预处理指令#define
声明一个常数,用以表明1年中有多少秒(忽略闰年问题):#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
1) #define 语法的基本知识(不能以分号结束,括号的使用)
2) 懂得预处理器将为你计算常数表达式的值,因此直接写出你如何计算一年中有多少秒而不是计算出实际的值。
3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数,用到UL(表示无符号长整型)。
写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个: #define MIN(A,B) ((A) <= (B) ? (A) : (B))。
----------------------
(2)数据声明(Data declarations)
用变量a给出下面的定义:
a) 一个整型数(An integer)
b)一个指向整型数的指针( A pointer to an integer)
c)一个指向指针的的指针,它指向的指针是指向一个整型数( A pointer to a pointer to an intege)r
d)一个有10个整型数的数组( An array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的。(An array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针( A pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer
----------------------
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
----------------------
(3)关键字static的作用是什么?
1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
(4)关键字volatile
volatile是一个类型修饰符(type specifier).volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
编译器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
例子:
1)并行设备的硬件寄存器(如:状态寄存器)
2)一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3)多线程应用中被几个任务共享的变量
(5)关键字Typedef:typedef是类型重定义,既然是重定义就不可能出现新的数据类型,用法:
用法一:可以减少代码的书写量
typedef struct student{
int data;
char name[10];
}stu, *pstu; -----------------指针直接操作stu s1,pstu ps1.data...
用法二:可以实现代码的复用性和可扩展性
如果一段代码没有扩展性和复用性,那么这段代码就不能算得上是一段特别规范的代码,就像我们为了实现代码的复用性,提高程序可读性的时候,用函数一样,提高代码的复用性和可扩展性是作为软件开发者必备的本领。一段好的代码,如果在别的项目中引用的话,如果功能类似,基本上改不了几行,这就是规范性的重要性(这里先不谈规范性,但是这个typedef的用法也涉及规范性,嘿嘿,所以规范是避免不了的)。就这么来说吧,假如我们定义了一个结构体
struct student{
int score;
char name[10];
};我们想把成绩改成double类型的,应为int的精度太低了,但是下面用到的地方可能都要改掉,但是,我们要是用typedef一下, 问题就变得简单多了,
typedef int typeitem;
struct student{
typeitem score;
char name[10];
};这样直接改typedef就行了,其他的代码根本不用动,这就是分层的原因,我们只改变最底层的,上层的东西根本不用变(就像在链表中,我们可以把它分为三层,纯数据层、节点层、head指针层,也就是整条链)这样分层处理问题会变得简单得多。还有就是平台不同可以兼容,就像有的平台不支持long double类型,但是你如果定义了long double 直接不能用,但是如果这么 typedef long double typeitem; 直接改成可以支持的类型就行啦,根本不用那么麻烦改下面的代码,这也是比较重要的用途。
----------------------
(6)关键字#pragma
#pragma pack(1) // 按照1字节方式进行对齐
#pragma pop() // 取消1字节对齐方式
(7)关键字const 它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。
说 const 定义的是变量,但又相当于常量;说它定义的是常量,但又有变量的属性,所以叫常变量。用 const 定义常变量的方法很简单,就在通常定义变量时前面加 const 即可,如:
const int a = 10; const 和变量类型 int 可以互换位置,二者是等价的,即上条语句等价于:int const a = 10;
用 const 修饰后和未修饰前有什么区别呢?它们不都等于 10 吗?
const VS define
- define是预编译指令,而const是普通变量的定义。define定义的宏是在预处理阶段展开的,而const定义的只读变量是在编译运行阶段使用的。
- const定义的是变量,而define定义的是常量。define定义的宏在编译后就不存在了,它不占用内存,因为它不是变量,系统只会给变量分配内存。但const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元。可以说,常变量是有名字的不变量,而常量是没有名字的。有名字就便于在程序中被引用,所以从使用的角度看,除了不能作为数组的长度,用const定义的常变量具有宏的优点,而且使用更方便。所以编程时在使用const和define都可以的情况下尽量使用常变量来取代宏。
- const定义的是变量,而宏定义的是常量,所以const定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查。这样就很容易出问题,即“边际问题”或者说是“括号问题”。
(8)关键字enum
enum枚举类型用法解析:https://blog.csdn.net/weixin_39918693/article/details/80454440
----------------------
(9)printf函数
- “%d”表示按十进制整型输出;
- “%ld”表示按十进制长整型输出;
- “%c”表示按字符型输出等。
(10)ARM里的大端格式和小端格式
大端(big endian): 低地址存放高有效字节
小端(little endian): 低字节存放低有效字节
(11)