1 C语言中枚举类型在其他地方的引用方法
首先初始化enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
枚举类型的引用enum week a = Mon, b = Wed, c = Sat;
这样变量 a,b,c分别得到了枚举类型week这总Mon ,Wed和Sat的值。
2 c语言中的# ## 可变参数宏 …和_ VA_ARGS _
1.#
假如希望在字符串中包含宏参数,ANSI C允许这样作,在类函数宏的替换部分,#符号用作一个预处理运算符,它可以把语言符号转化程字符串。例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字符串。该过程称为字符串化(stringizing).
#incldue <stdio.h>
#define PSQR(x) printf(“the square of” #x “is %d.\n”,(x)*(x))
int main(void)
{
int y =4;
PSQR(y);
PSQR(2+4);
return 0;
}
输出结果:
the square of y is 16.
the square of 2+4 is 36.
第一次调用宏时使用“y”代替#x;第二次调用时用“2+4"代#x。
2.##
##运算符可以用于类函数宏的替换部分。另外,##还可以用于类对象宏的替换部分。这个运算符把两个语言符号组合成单个语言符号。例如:
#define XNAME(n) x##n
这样宏调用:
XNAME(4)
展开后:
x4
程序:
#include <stdio.h>
#define XNAME(n) x##n
#define PXN(n) printf(“x”#n" = %d\n",x##n)
int main(void)
{
int XNAME(1)=12;//int x1=12;
PXN(1);//printf(“x1 = %d\n”, x1);
return 0;
}
输出结果:
x1=12
3.可变参数宏 …和_ VA_ARGS _
VA_ARGS 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏_ VA_ARGS _就可以被用在替换部分中,替换省略号所代表的字符串。比如:
#define PR(…) printf(VA_ARGS)
int main()
{
int wt=1,sp=2;
PR(“hello\n”);
PR(“weight = %d, shipping = %d”,wt,sp);
return 0;
}
输出结果:
hello
weight = 1, shipping = 2
省略号只能代替最后面的宏参数。
#define W(x,…,y)错误!
3 关于ARM程序内存映射说明
如果arm带norflash
程序一般默认分下面几个段,代码段(默认名称一般为.text或.code),只读数据段(默认名称一般.ro),有初始化值的读写数据段(默认名称一般.rw), 无初始化值的读写数据段(默认名称一般为.zi),还有堆栈段。当然你还可以定义自定义的段,自定义的段需指明是什么类型的段,是只读段,还是读写段。
代码段当然就是代码了,一般这个是只读的,因为如果可以允许随意修改代码段的机器代码,会造成无法预知的后果,因此这个段可以映射在norflash中。
只读数据段一般是恒常量,恒常量么,当然是只读的,所以这个也可以映射在norflash中。
.rw段一般包括有初始化值的全局变量,这个由于是变量,当然不能映射在norflash中了。
.zi段一般包括不带初始化值的全局变量,这个也是变量,当然也不能映射在norflash中。
堆栈段同样是读写段,不能映射在norflash中。
上述各段的放置位置是由链接器链接时由链接脚本决定的,如果你没有设置自己的链接脚本,编译器会按默认的链接规则分布上述各段,如果你指定了链接脚本,会按你自己定义的链接脚本的链接顺序来链接为可执行程序。
一般当链接地址指向RAM中时,默认的链接顺序是这样的, 从低地址向高地址,首先是代码段,然后是只读段,然后是RW段和ZI段,再上面一般是堆,最上面是堆栈段,堆栈段是向下增长的。
如果链接地址设置在FLASH中时,默认的链接顺序一般是,代码段和只读段放在FLASH中,其他段放在RAM中。
如果自己定义链接脚本,虽然可以将RW段和ZI段放在FLASH里编译过去,但程序写RW段和ZI段是不会成功的,因此程序执行也不会是正确的。
4.NORflash中为什么可以运行程序,而Nandflash不行?
由于Norflash可以和ram一样实现随机访问,Nandflash的读是一次读一块,一般是512个字节,不能实现随机访问。下面是网上大神对这个问题的解释。
代码不一定要在RAM中才能执行,CPU从一个存储器件中读取指令并执行,主要看的是该存储器能否实现随机读取(访问任意地址)。基于这个原理很多flash被修改成可以直接执行程序。STM是如何修改的,没有研究过。见过一种做法是,做一个缓冲区(只用来缓冲执行代码)将FLASH的代码读到该区中,有点类似MPU的感觉。
对于RAM,最初设计是用来存放变量的,可以说是栈空间,由CPU的SP指针指向。
以PC机为例(主流操作系统也是这样),将代码从硬盘从读取,存放到内存中(DDR),系统则会将该内存定义为READ ONLY也就是ROM的意思。对CPU来说,该区域并不是什么DDR或者RAM,只是一个可以随机读取代码的存储器,当然CPU也不关心这个是ROM,DDR,还是FLASH。
C语言中声明和定义的区别
从本质角度来说,定义需要分配内存,声明不需要分配内存。
声明是针对全局变量和函数来说的。
定义除了全局变量和函数,还针对局部变量。
例如,对一个全局变量。
int a; //定义全局变量a。
extern int a;//声明全局变量a,表示在其他地方有int a的定义。其他在文件中要引用全局变量a就得使用在相应的地方使用extern 去修饰。
全局变量只能定义一次,但是声明可以多次。