Linux内存单位
- 栈区:占用内存大小 最大值: 大概 2M 大于2M会栈溢出 平台有关系的
- 堆区:占用内存大小 最大值: 大概80% 40M没有任何问题,基本上不用担心 堆区很大的
// malloc 在堆区开辟的内存空间 , (动态的范畴) ,C的开发过程中,不能出现,野指针,悬空指针
void dynamicAction() {
int * p; // 野指针 没有地址的,空的
// void * 可以任意转变 int* double *
int * arr = malloc(4 * 1024 * 1024); // 1024x1024字节,堆区开辟 4M
printf("dynamicAction函数,arr自己的内存地址:%p,堆区开辟的内存地址:%p\n", &arr, arr);
// C工程师,堆区开辟的空间,必须释放
free(arr); // 释放掉
arr = NULL; // 重新指向一块内存地址00000
printf("dynamicAction函数2 堆区开辟的内存地址:%p\n", arr); // 悬空指针
}
// 字符串
int mainT2() {
char str[] = {'D', 'e', 'r', 'r', 'y', '\0'};
str[2] = 'z'; // 这里能修改?
printf("第一种方式:%s\n", str); // printf 必须遇到 \0 才结束
char * str2 = "Derry"; // 隐士 Derry+\0
str2[2] = 'z'; // 会奔溃
printf("第二种方式:%s\n", str);
return 0;
}
C运行单位
- C是以函数作为基本单元,并且从上往下进行执行,所以函数A调用函数B的时候需要先将函数B写在函数A前面,为了方便开发所以出现了头文件进行函数声明,然后在实现,这样可以先引入声明文件就可以不用区分函数的先后顺序。
- JAVA 是以类作为基本单位进行编辑,所以在类里面函数不分先后都可以找到并执行。
指针
- 指针是存放对应变量的地址,可以通过指针在改变变量的值
- 指针优先级 ()> [] > *
指针函数 函数指针
- 指针函数就是返回值为指针的函数。
- 函数指针是声明函数类型的变量,可以将对应的函数赋值给这个变量。
数组
- 可以用一个指针指向数组首地址,这样可以通过指针操作数组,数组的内存地址 == 第一个元素的内存地址 == &arr
指针数组
数组的每个元素存放的都是指针
数组指针
数组指针一般是行指针,实质上可以用做表示多维数组
共用体
共用体的内存占用是根据成员里面最长的那个决定的,而结构体是多个成员加起来的总和
//共用体声明
union Data{
int I;
float f;
char str[2];
} data;
结构体
- 将多个变量封装成一组称为结构体
-
结构体声明后可以不用像java那样实例化,可以直接使用 + 给结构体分配内存的时候是遵循内存对齐的规则(因为不用内存对齐,访问一个变量会访问两次来拼凑一个完整有效数据,为了提高执行效率,所以用了内存对齐,比结构体中有 int 、short 两个变量,实际上分配内存为8个字节而不是6个字节)
struct Cat {
char name[10];
int age;
};
int main() { // 栈
// 结构体
struct Cat cat = {"小花猫", 2};
// VS的写法:Cat * catp = &cat;
struct Cat * catp = &cat;
catp->age = 3;
strcpy(catp->name, "小花猫2");
printf("name:%s, age:%d \n", catp->name, catp->age);
return 0;
}
int main() { // 堆
// VS的写法:Cat2 * cat = (Cat2 *) malloc(sizeof(Cat2));
struct Cat2 *cat = malloc(sizeof(struct Cat2));
strcpy(cat->name, "金色猫");
cat->age = 5;
printf("name:%s, age:%d \n", cat->name, cat->age);
// 堆区的必须释放
free(cat);
cat = NULL;
return 0;
}
struct Workder_ {
char name[10];
int age;
char sex;
};
// VS的写法:typedef Workder_
typedef struct Workder_ Workder_; // 给结构体取别名
typedef Workder_ * Workder; // 给结构体指针取别名
// C库的源码,系统源码...,为什么 typedef 还取一个和结构体一样的名字(兼容代码的写法,保持一致)
int main() {
// 以前 Clion工具 必须加上 struct VS又不用加 代码差异化大
// struct Workder_ workder1 = malloc(sizeof(struct Workder_));
// 现在 (兼容代码的写法,保持一致)
Workder_ workder1 = malloc(sizeof(Workder_));
// VS CLion 他们都是一样的写法
Workder workder = malloc(sizeof(Workder_));
return 0;
}
库文件(动态库、静态库)
APK 中一般用动态库比较多,考虑的主要是apk的大小