ios第十天
/ 利用关键字 static 修饰的变量 叫做静态变量 并且存储在静态区
// 特点1 如果你不给初值的话 默认 为0
// 特点2 只初始化一次
// 在main函数 上面 是全局静态变量
// 在main函数 里面 叫局部静态变量 作用域是大括号内
void function(){
int a = 5;
int b = 6;
printf("%d,%d",a,b);
}
int main(int argc, const char * argv[]) {
// 内存划分为5个区域
// 栈区 堆区 静态区 常量区 代码区
// 内存地址 由高到低
// 学习目标 按顺序记忆
#pragma mark -- 代码区
// 电脑的存储 都是以二进制数据进行存储的
// 咱们写得代码 会被系统转化成二进制数据 存储代码区
#pragma mark -- 常量区
// 常量区 存储的常量特点
// 把 h 更改成 w
// char *str = "zhuang";
// 常量 是程序运行期间 不能改变量
// str = "haha"; // 指针的赋值 就是重指向
// char str[] = "zhuang";
// str[1]='w';
// 数组名字 地址 数组首元素的地址
// 数组首元素的常量地址
// 是把常量字符串 拷贝到栈区
#pragma mark -- 静态区
// 静态区: 存储两种变量
// 1. 静态变量
// 2. 全局变量
// 3. 静态区变量 保存周期:直到程序运行结束 静态变量才会被释放(伴你到永生)
#pragma mark -- 栈区
// int num1 = 5;
// int num2 = 10;
// int num3 = 15;
// printf("%p\n",&num1);
// printf("%p\n",&num2);
// printf("%p\n",&num3);
// 栈区有多大?
// 大概7M-8M
// char str[8187 * 1024] = {0};
// 出栈 入栈的规则
// 先入栈的 后出栈 先入栈的 在栈低
// 入栈 可以叫 压栈
// 出栈 的顺序 从栈顶开始 出栈
// int num1 =5;
// int num2 = 10;
// int num3 = 15;
// function();
// 之所以栈区容量不是特大 又不出现奔溃的现象 是因为 栈区 频繁进行 出栈 和入栈 只要一次性 不把栈空间堆满 不会轻易出现崩溃
// 定义变量的时候 切记 给初值 避免出现莫名其妙的问题
#pragma mark -- 堆区
// 堆区 是程序员开辟空间 是程序员释放空间
// 手动开辟空间 手动释放空间
// 堆区空间 大概就是咱们内存全部空间
// 开辟空间函数
// void * 表示无类型指针 可以转换成任何类型的指针
// void *malloc(<#size_t#>)
// size 开辟空间大小 开辟多少字节空间
// 给整型指针p 指向的位置 开辟了4个字节的 堆内存空间
// int *p = malloc(4);
// *p = 10;
// printf("%d \n",*p);
//
// char *str = malloc(8);
// strcpy(str, "wang"); // 正确的
// strcpy(str, "wangwangwang");// 错误的, 开辟多少空间 就要用多少空间 不要超过开辟的空间
// printf("%s",str);
// int *p1 = malloc(4);
// *p1 = 5;
// short *p2 = malloc(4); // 开辟多少空间 最好你就用多少
// *p2 = 10;
// *(p2 + 1) = 15;
//
// 释放空间函数
// free(<#void *#>)
// 1 .标记删除 不会抹去该空间存储的数据 只会把这块空间标记为可用
// 2. 把指针置为空
// 开辟空间
// int *p = malloc(4);
// // 使用空间
// *p = 10;
// printf("%d\n",*p);
// // 释放空间
// free(p);
// p =NULL;
// int *p = malloc(sizeof(int) * 5);
// for (int i = 0; i < 5; i++) {
// *p = i + 1;
// p++;
// }
// // 指针地址发生变化 释放了本不属于你开辟的区域 这时候程序崩溃
//
//
// // 修改 把指针移回去
// for (int i = 0; i < 5; i++) {
// p--;
// }
// free(p);
// p = NULL;
//
//**********************************************************************
// char str[] ={"dj5s5f"};
// // 计算出有多少个数字
// int count = 0;
// for (int i = 0; i < strlen(str); i++) {
// if (str[i] >= '0' && str[i] <= '9') {
// count++;
// }
// }
// char *strValue = malloc(count + 1);
// int index = 0;
// for (int i = 0; i < strlen(str); i++) {
// if (str[i] >= '0' && str[i] <= '9' ) {
// strValue[index] = str[i];
// index++;
// }
// }
// strValue[index] = '\0';
// printf("%s",strValue);
// free(strValue);
// strValue = NULL;
//
//*******************************************************************
// char *words[3] = {0};
// char str[] = {0};
// for (int i = 0; i < 3; i++) {
// printf("请输入一个字符串");
// scanf("%s",str);
// printf("%lu",strlen(str));
// words[i] = malloc(strlen(str) + 1);
// // 保存字符串
// strcpy(words[i], str);
//
// }
//
//
//
// for (int i = 0; i < 3; i++) {
// printf("%s",words[i]);
// free(words[i]);
// words[i] = NULL;
// }
//
// ************************************************************
// 其他分配堆内存函数
// 在堆内存当中 开辟 n * size 个空间 并且把开辟的内存空间清零
// 因为有一个清零的过程 所有效率偏低
// calloc(int n , size);
// 重新分配函数
// realloc(原来分配的地址, 新空间大小)
// 情况1: 如果原来分配的地址 可以扩充空间 那么就在原地址扩充
// 情况2: 如果原来分配的地址 不能扩充了 那么系统会重新分配一个空间 并且把原来地址存储的数据拷贝到新空间里 然后系统自动释放原地址的空间
//
// int *p_old = malloc(10);
// int *p_new =realloc(p_old, 15);
// printf("%p %p\n",p_old,p_new);
//
//
// 内存操作函数
// 把开辟的空间 多少字节 重置成C
// memset(开辟的空间的指针, int c, 字节数)
// 用途: 把开辟好的空间 清零
// int *p = malloc(sizeof(int) * 4);
// for (int i = 0; i < 4; i++) {
// p[i]=i + 5;
//
// }
// // 清零
// memset(p, 0, sizeof(int) * 4);
// for (int i = 0; i < 4; i++) {
// printf("%d",p[i]);
// }
// 内存拷贝函数
// 从来源 拷贝 到 目的地 多个字节
// memcmp(目的地, 来源, 字节数)
// 内存比较函数
// 两个地址 按字节 进行比较 返回第一个不同的差值
// memcmp(指针1, 指针2, 字节数)