从linux了解世界
分类: 嵌入式
2016-01-24 22:21:55
C语言预定义宏:
__FUNCTION__当前函数名,__FILE__ 当前文件名,__LINE__当前行号(不考虑执行顺序,只考虑该执行代码在文件中第几行)
printf(“filename is%s,functionname is %s,linenumber is %d",__FILE__,__FUNCTION__,__LINE__);
整型常量默认int型,浮点数常量默认型double,考虑可移植性(怕溢出)可以加后缀:
#define EXAMPLE (123456789UL)
Gcc不能主动和c++库链接,gcc –lstdc++就和g++一样了
Gcc –E 调用cpp预处理
Gcc –S 调用cc编译
Gcc –c 调用as汇编
Gcc –I 目录将目录加入寻找头文件的目录集
Gcc –L目录将目录加入寻找库文件的目录集
Gcc –lname在库文件目录集中找libname的库文件
Gcc –Dname相当于在程序头加入#define name 外部控制#ifdef之类的预编译
宏展开下的:#字符串化
#define A(x) #x
Printf(A(x));相当于printf(“x”);
宏展开下的:##连接符号
#difine A(x) (x ## _day) 这两种#的用法只有宏展开时有用,也就是预处理时有用
C语言编译器32个关键字:
xxx_t中的t代表xxx_t是个typedef
enum更常用在打包一组宏
enum{A,B}相当于#define A 0,#define B 1。默认从零开始定义
定义一个字符指针指向字符串最好加const修饰一下,虽然没什么卵用,但是看起来正规专业const char *str=“string\n”(为什么说没什么卵用的原因是被const修饰的符号不能出现在=的左面但是可以在右面,所以只要不是在ro段就可以间接修改,const不会改变变量的位置,c++会改变)
const char a[]="haha";
char *b=a;
*b='d';
printf(":%s",a);daha输出
unsigned char *const str一般当str是固定硬件资源时用(因为硬件地址固定),例如lcd的缓存
const unsigned char * const str用在rom的操作
想要一段可以改的字符串:char str[]=“string\n”这样实际上是把”string\n”这个字符串一个一个赋给数组,效率上没变化反而会多占用空间,只是编译器方便程序员的操作。当数组第一次初始化时,编译器可以帮我们翻译成一个一个赋值,第二次赋值编译器就不会帮我们了,因此只能一个一个赋值:
char str[]=”test”初始化正确
str[]="haha"错误
为了解决这个问题,提供一组函数例如strcpy进行赋值。(strcpy绝对不会在真正工程中使用,这是一个典型的内存泄漏函数,strncpy可以避免,原因很简单不说了)
业界不成文规定,char定义的一定是个字符或者字符串(ascii码,因为基本上只用到7位,不用考虑正负),unsigned char是常规数据
int(*p)[5]可以访问列为5的二维数组
结构体大小一定是计算机位数的倍数(4),但是里面内容顺序不同会影响大小
Linux运行程序时4G虚拟空间内存分布
------------------------------4g
内核空间
------------------------------3g
栈空间
------------------------------
堆空间
------------------------------
data段(初始化的全局变量和静态局部变量,rw数据段),bss段(未初始化的zi段)
------------------------------
text段(ro段,代码和ro数据)括号内的名字是armcc中段的名字
------------------------------
内核保留空间
------------------------------0
程序链接后的可执行文件中有:代码段,ro数据段,rw数据段并记录zi段大小和位置。
linux中的命令:size可以看各个段,nm看静态标号(链接地址)
static应用于函数(只能本文件使用防止重命名)、全局变量(只能本文件使用防止重命名)、局部变量(改变变量存放位置,从栈到rw区,程序一开始就分配好空间)
.S可以使用gcc中的c语言的预处理器,所以汇编文件一般都S后缀名