12月14号 宏定义、枚举和动态分配内存
2015-12-14 17:02
316 查看
一、宏定义
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个字节
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个字节
相关文章推荐
- 第14周项目4(3)输出所有路径
- 第十六周 项目一 验证算法(6) 堆排序
- device_add()浅析
- 第14周SHH数据结构-【项目1-(2)验证分块查找算法】
- 第十五周项目一:验证算法
- 第十六周--归并排序算法的改进
- 第十六周——【项目2 - 大数据集上排序算法性能的体验】
- js 异步上传图片 限制图片的格式大小
- 浏览器兼容测试最坑爹,费时费力;今天推荐一个在线的浏览器兼容测试服务
- logback与Log4J的区别
- TinyOS论文09:Random Testing of Interrupt-Driven Software
- 浏览器兼容测试最坑爹,费时费力;今天推荐一个在线的浏览器兼容测试服务
- gulp压缩文件
- 第12周项目4(2)输出简单路径
- 第十二周 项目1 图基本算法库
- 第十五周 项目1 堆排序
- 第十六周 项目1.4——验证算法
- 第8周项目1 建立顺序串的算法库
- 第16周实践项目-基数排序
- springmvc url 路径映射