一、宏定义
1)什么是宏定义?
用一个字符串代替一个数据
2)为什么要用宏定义?
1.为了让一些数据有意义
#define kAPPSecret aafjall221adfaf
#define kAPPKey 124242
2.类似于内敛函数的意思
#define kAdd(a, b) ((a)+(b))
#define kmultiple(a, b) ((a)*(b))
3.可以做输出日志的开关
#if 1
#define Debug(x) printf("%s\n", x)
#else
#define Debug(x)
#endif
int main(int argc, const char * argv[]) {
Debug("in development");
return 0;
}
二、枚举
*宏定义和枚举的区别
宏定义是一个值/表达式 不是一种类型
枚举是一种类型,可以定义枚举类型的一个变量
//定义了一个枚举,类型名字是 kAnimalCategory
typedef enum{
kAnimalCategoryBuru = 2,//默认从0开始
kAnimalCategoryMaoke = 5,//3 后者会在前者之上 + 1
kAnimalCategoryFeiqin = 7,//4
kAnimalCategoryZoushou//5
} kAnimalCategory;
typedef struct{
char *name;
kAnimalCategory type; //动物的类别 1 2 3 4
}Animal;
int main(int argc, const char * argv[]) {
Animal dog;
dog.name = "xiaohuang";
dog.type = kAnimalCategoryZoushou;
return 0;
}
三、动态分配内存
1)区分
1.自动分配内存:当定义以基本类型的变量的时候,系统会为这个变量自动分配内存,这个内存在堆上。当作用域结束,系统会自动将这个内存回收。
2.动态分配内存:开发人员自己想系统申请的内存空间,申请的内存位于栈上,当作用域结束之后,系统是不会自动收回内存的。这个内存必须有开发人员自己去释放。如果不释放,就内存泄露了。
2)什么时候需要动态分配内存
程序运行过程中,需要保存/记录相应地数据,但是又没有提前准备好内存,那么就需要临时动态分配内存。
3)使用的函数
void *malloc(size_t);
size_t:希望申请的内存空间(单位是字节byte)
void *:系统一开始不知道你需要存放什么数据,不同的数据需要的内存空间不一样,所以默认就是给一个void *,泛指所有指针类型(char *,int *,struct *),当在使用的时候必须将void *转化为相应的类型。如果没有申请成功,那么返回值为NULL。
4)释放内存free(void *)
注意:free里面的参数必须是指针,这个指针指向的内存必须是动态分配的。
四、计算结构体内存空间
原理:如果结构体内部拥有多种数据类型,那么以占据内存字节数最高的类型对齐
typedef struct{
char *name;
int age;
}Person;//16个字节
char * 占据8个字节,int占据4个字节
所以age变量自动向name对齐。整个占据16个字节
typedef struct{
char name;
int age;
}Person;//8个字节
typedef struct{
char name[2];
int age;
}Person;//8个字节
typedef struct{
char name[6];
int age;
}Person;//12个字节