iOS开发之c语言基础Lesson-10 动态内存管理 上课笔记 与 试题练习

//函数声明

int max(int a, int b);

char * getString();

int main(int argc, const char * argv[]) {

//////////////////Lesson 10 动态内存管理 课堂笔记 和 练习

///////复习上周所学

/////////常量和变量的区别:

//常量中的内容不能被修改,只能访问;

//变量中存储的数据时可以随时修改的。

//

//const 关键字的作用: 修饰变量不可改变。当做常量使用

//  const int a = 10;

////////以下变量谁可不变

//口诀:看const修饰谁, 谁就不可变, 将数据类型 int 去掉 (const后面跟的变量,*也是一体的)

//    int b = 30;

//    const int *p1 = &b; //*p1不可变; p1指针变量,*p1指针变量指向的存储空间。const 修饰*p1, 不能通过指针变量*p1修改指向的存储空间上的数据,但是p1可以重新赋值。

//

//    int *const p2 = &b;//p2不可变,const修饰p2,p2中存储的数据不可更改,但是可以通过指针变量p2(使用*p2),修改指向的空间上的数据。

//

//    int const *p3 = &b;//*p3不可变,同p1

//

//    const int *const p4 = &b;//p4,*p4不可变

/////////不同数据类型定义的变量所存储的内容:

//int, short, long: 存储整数,整型数据。

//float, double:存储小数,浮点型数据。

//char:字符型数据。

//char *, int *, short *: 存储地址

//struct student: 存储结构体成员信息

//struct student * :存储结构体变量的地址

/////////指针数组

//常量区上存储的数据不可更改。

//    char *str1 = "iPhone"; //str1存储常量字符串 iPhone 首地址;

//

//    char *str2 = "Rose";

//    char *str3 = "Tom";

//    char *str4 = "Jack";

//    char *str5 = "Android";

//

//    //交换指针变量

//    char *temp = str2;

//    str2 = str3;

//    str3 = temp;

//    printf("%s \n", str3);

//

//

//    char *strings[5] = {"iPhone", "Rose", "Tom", "Jack", "Android"};

//    //strings[0] == str1

//

//

//    char *tp = strings[1];

//    strings[1] = strings[2];

//    strings[2] = tp;

//

//    printf("%s \n", strings[2]);

//

//    printf("%p, %p", str1, strings[0]); //同一个字符串,是一个地址

////////// * 的作用

//    int c = 10;

//    int *p = &c;  //定义指针变量时,*的作用只是为了告诉编译器,后面的变量是一个指针变量,用来存储地址。

//

//    *p = 30; //此时,* 的作用,是根据指针变量找到指向的存储空间,并且存储数据30

//

//    printf("%d \n", *p);//同上

//

////////////////////动态内存

//内存中的5分区

//1.栈区:主要存放局部变量或者数组,定义在函数内部,当函数调用时开辟空间,当函数结束后回收空间,内存有 系统 进行分配和回收。

//2.堆区:堆区内存由 开发人员 手动开辟,手动释放。

//3.全局、静态区:存放全局变量,以及静态变量; 程序运行时,开辟空间,程序运行结束空间回收。由 系统 进行管理。

//4.常量区:存放常量;整型,浮点型,字符型,字符串型; 常量区空间上得内容不可修改,read-only

//5.代码区:存放程序编译之后形成的CUP指令,告诉计算机程序如何运行。

//////

//    int a = 10, b = 20;

//

//    printf("%d\n", max(a, b));

//

//    printf("%s", getString());

//

////////

//如何在堆区空间上存放数据。

//如何在堆区开辟空间

//malloc在堆区开辟n个字节大小的空间,并且返回空间的首地址。返回值类型void *泛型,代表任意指针的类型。

//如果申请 8 个字节的空间, 使用不同的指针类型变量接收, 存储的数据大小不同。

//char *: 8个字符

//int *: 2个整数

//short *: 4个整数

//long *: 1个整数

//    char *p = malloc(7); //手动开辟空间

//

//    strcpy(p, "iPhone");

//    printf("%s\n", p);

//

//    strcpy(p, "Apple");

//    printf("%c\n", *(p + 3));

//

//    free(p);    //手动释放空间, 释放时需要给定开始地址; 释放只是把空间还给系统,属于标记删除,不清楚内容。

//    printf("%p\n", p); //虽然释放了空间,但是p存的地址并没有清空

//    printf("%s\n", p);

//

//    p = NULL;//清空指针变量中得地址,指向无效的空间

//

/////堆区空间常见的问题:

/*

1.野指针错误:访问一块没有权限的空间,没有获得空间的使用权。存在安全隐患;解决方案:当把空间还给系统之后,将指针变量中存储的地址清空 即:赋值NULL

2.过度释放:对一块空间free多次,过度释放会立即导致crash.

3.内存泄露:空间没有及时的释放,造成内存堆积。就是没有free; 安全隐患.

*/

//开辟空间存储5个整数, 赋值10 - 20

//    int *a = (int*)malloc(sizeof(int) * 5);

//

//    for (int i = 0; i < 5; i++) {

//        *(a + i) = arc4random() % (20 - 10 + 1) + 10;

//        printf("%d ", *(a + i));

//    }

//

//    for (int i = 0; i < 5 - 1; i++) {

//        for ( int j = 0; j < 5 - 1 - i; j++) {

//            if (*(a + j) < *(a + j + 1)) {

//                int temp =*( a + j);

//                *(a + j) = *(a + j + 1);

//                *(a + j + 1) = temp;

//            }

//        }

//    }

//    printf("\n");

//    for (int i = 0; i < 5; i++) {

//        printf("%d ", *(a + i));

//    }

//

//    free(a);

//    a = NULL;

//    有?字符串,其中包含数字,提取其中的数字.要求动态分配内存保存

//    char str[]= "lan5ou2015032056", *p = NULL;

//

//    char *a[20] = {0};

//    int count = 0;

//    int i = 0, j = 0;

////方法1

//    while (str[i] != ‘\0‘){

//        if (str[i] >= ‘0‘ && str[i] <= ‘9‘) {

//            a[j] = (char*) malloc(sizeof(char));

//            count++;

//            a[j] = &str[i];

//            j++;

//        }

//        i++;

//    }

//    for (int i = 0; i < count; i++) {

//        printf("%c ", *(a[i]));

//    }

/////方法2

//   // 获得数字个数

//   i = 0;

//    while (str[i] != ‘\0‘){

//        if (str[i] >= ‘0‘ && str[i] <= ‘9‘) {

//            count++;

//        }

//        i++;

//    }

//    //开辟空间

//    char *num = malloc(count + 1);

//    //存储字符

//    j = 0;

//    i = 0;

//    while (str[i] != ‘\0‘){

//        if (str[i] >= ‘0‘ && str[i] <= ‘9‘) {

//             *(num + j) = str[i];

//            j++;

//        }

//        i++;

//    }

//    *(num + j) = ‘\0‘;

//    printf("%s ", num);

//    free(num);

//    num = NULL;

//方法3

//    i = 0, j = 0;

//    while (str[i] != ‘\0‘){

//        if (str[i] >= ‘0‘ && str[i] <= ‘9‘) {

//            p =  realloc(p, sizeof(char));

//            count++;

//            *(p + j) = str[i];

//            j++;

//        }

//        i++;

//    }

//

//    printf("数字个数:%d, %s ",count, p);

//    free(p);

//    p = NULL;

//2. 输?入3个学员的姓名,动态分配内存保存学员姓名,并在最后输出

//存储3个单词,意味着需要开辟3次空间,每次开辟空间都会返回对应的首地址, 所有为了存储3个地址,定义指针数组存储。

//    char *word[3] = {0};

//    char temp[20] = {0}; //存储控制台输入的字符串

//

//    for (int i = 0; i < 3; i++) {

//        printf("\nInput [%d] name :", i + 1);

//        scanf("%s",temp);

//        word[i] = malloc(strlen(temp) + 1);//根据输入的字符串动态在堆区分配空间

//        strcpy(word[i], temp);

//    }

//

//    for (int i = 0; i < 3; i++) {

//        printf("%s ", *(word + i));

//        free(word[i]);

//        word[i] = NULL;

//    }

////////其他内存分配函数

//////calloc(n, size_t)  c---clear 多了一步空间数据的清理操作,但是清理操作效率较低。

//    //分配n个size?大?小的空间,并且把该内存上的所有字节清零。 分配n个size大小的空间

//    int *ptr = calloc(5, 4);

//

//    free(ptr);

//    ptr = NULL;

//

//

//    //////realloc 内存重新分配函数

//    char *pstr = malloc(10);

//    //10个空间不够,重新分配20个,不是追加

//    char *pstr1 = realloc(pstr, 200);  //工作原理:先以之前的开始地址作为基准,重新分配新的空间,如果此时发现剩余空间不足,会寻找新的空间。此时返回的地址,就和之前不一样的,另外realloc内部集成了将之前空间free的操作。

//    printf("%p, %p", pstr, pstr1);

//    free(pstr1);   //只需释放realloc的空间即可。

//    pstr1 = NULL;

//    pstr = NULL;

//

///////内存操作函数

// void *memset(void *s , int c , size_t n)

// 从s指向的内存开始初始化n个字节的内容为c

//    int memcmp(const void *buf1, const void *buf2, unsigned int count)

//

//    ?比较buf1和buf2指向的内存是否相同,?比较count个字节

//    void *memcpy(void *dest,const void*source , size_t n)

//

//    从source指向的内存开始拷?贝到dest,拷?贝n个字节

// 定义两个整型指针,分别?用malloc、calloc对其分配空间保存3个元 素,malloc分配的空间?用memset清零,随机对数组进?行赋值随机范 围1-3,赋值后?用memcmp?比较两个数组。如果相同打印Good!否则 打印Failed...

//

//    int *ip1 = (int *)malloc(3 * sizeof(int));

//    int *ip2 = (int *)calloc(3, 4);

//

//    memset(ip1, 0, 12);  //清 0 操作

//

//    for (int i = 0; i < 3; i++) {

//        *(ip1 + i) = arc4random() % 3 + 1;

//        *(ip2 + i) = arc4random() % 3 + 1;

//        printf("%d  %d\n",*(ip1 + i), *(ip2 + i));

//

//    }

//    if ( memcmp(ip1, ip2, 1) == 0) {

//        printf("GOOD");

//    }else{

//        printf("Failed");

//    }

//

return 0;

}

//函数实现

int max(int a, int b){

return a > b ? a : b;

}

//char string[] = "Welcome to Lanou iOS!"; //放在这里是可以,不过不太安全

char *getString(){

// char string[] = "Welcome to Lanou iOS!";  // //数组string,是在函数内部定义的,属于局部变量,存储在栈区,当函数执行结束,数组空间被系统回收。外界拿到地址,将访问一块已经回收的空间。所以,要想安全的返回,必须保证返回之后空间还在。

// static char string[] = "Welcome to Lanou iOS!"; //设置成静态数组

char *string = "Welcome to Lanou iOS!";     //返回的是常量区Welcome 。。。。,首地址;

return string;

}

时间: 2024-11-04 09:06:45

iOS开发之c语言基础Lesson-10 动态内存管理 上课笔记 与 试题练习的相关文章

iOS开发之c语言基础 扩展知识点 及 企业面试题

1 // 2 // main.m 3 // LessonScale 4 // 6 // Copyright (c) 2015年 Ashen. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 //当程序编译时,只会编译.m文件,不会编译.h文件 11 //#import 比 #include ,要略胜一筹,等通过#import多次导入头文件时,只会将内容拷贝一次 12 #import "Header.

李洪强iOS开发之OC语言基础知识

OC语言基础知识 一.面向对象 OC语言是面向对象的,c语言是面向过程的,面向对象和面向过程只是解决问题的两种思考方式,面向过程关注的是解决问题涉及的步骤,面向对象关注的是设计能够实现解决问题所需功能的类. 术语:OO面向对象.OOP面向对象编程   二.类 (一)关于类 类的设计只关注三个东西:类名.属性和方法 注意:一般名词都是类,拥有相同属性和行为的对象都可以抽象为一个类,类名是标识符的一种,需要符合规范,通常类名的第一个字母大写,且不能有下划线,如果有多个单词则使用驼峰标识.在对方法进行

我是黑马-----ios开发之C语言基础

C语言在学习中的重难点: 1)运算符:自增,自减. 2)进制:各种进制转换.原码.反码.补码. 3)数组:一维数组,二维数组,多维数组. 4)循环:多重循环嵌套.查找.排序. 5)函数:普通函数调用.递归函数的调用. 6)指针:一级指针.多级指针.数组指针,指针和数组.函数.结构体.之间的关系. 7)内存管理:C语言的内存管理问题.内存泄露.野指针. 8)有参宏及条件编译. 9)多文件开发 前期学习C语言的关键输入输出函数:printf()和scanf() a++与++a的区别: 运算的顺序就是

iOS开发之c语言基础Lesson-08 指针 上课笔记 与 试题练习

1 ////////////////Lesson 08 指针 课堂笔记 与练习///////////// 2 3 //指针:本质是一个指针变量,只不过该变量用来存储地址. 4 //地址:内存单元的编号,也是一个数,只不过是以0x开头的十六进制数. 5 6 // int a = 10; 7 // int *p = &a; //定义一个指针变量,将a的地址给指针变量p:p指向a 8 // a = 20; //直接访问 9 // printf("%d ", *p); 10 // *p

iOS开发之c语言基础Lesson-11 函数指针 上课笔记 与 试题练习

main.m 文件 9 #import <Foundation/Foundation.h> 10 #import "Pointer.h" 11 ////////////////Lesson 11 函数指针 课堂笔记 与 习题练习//////////// 12 13 14 //函数指针:指向函数的指针叫做函数指针,用来存储函数的地址 15 //函数名代表函数的入口地址 16 17 18 //回调函数; 函数指针变量,存储对应的函数的地址 19 //给函数指针类型,取一个新的名

李洪强iOS开发之C语言重难点

  C语言学习的重难点 写程序的三个境界: 照抄的境界,翻译的境界,创新的境界 1  伪代码: 描述C语言的编程范式 范式: 规范的一种表示 对于C的范式学会的话,C, C++ Java 都会了 2 运算符的自曾与自减 3 进制转换与数据在内存中的表示 4 循环嵌套 5 多维数组 6 函数递归 7 指针-是一把双刃剑 8 内存管理 9 待条件的宏

李洪强iOS开发之OC语言前期准备

OC语言前期准备 一.OC简介 Oc语言在c语言的基础上,增加了一层最小的面向对象语法,完全兼容C语言,在OC代码中,可以混用c,甚至是c++代码. 可以使用OC开发mac osx平台和ios平台的应用程序. 拓展名:c语言-.c  OC语言.-m  兼容C++.-mm 注:其实c语言和oc甚至任何一门语言都只是我们为了实现一些功能,达到一些效果而采用的工具,抛开语法的差别外,我想最重要的应该是在解决问题的时候考虑的角度和方法不一样而已,然而这也构成了学习一门语言的重要性. 二.语法预览 (一)

李洪强iOS开发之OC语言构造方法

OC语言构造方法 一.构造方法 (一)构造方法的调用 完整的创建一个可用的对象:Person *p=[Person new]; New方法的内部会分别调用两个方法来完成2件事情,1)使用alloc方法来分配存储空间(返回分配的对象):2)使用init方法来对对象进行初始化. 可以把new方法拆开如下: 1.调用类方法+alloc分配存储空间,返回未经初始化的对象 Person *p1=[person  alloc]; 2.调用对象方法-init进行初始化,返回对象本身 Person *p2=[p

iOS开发之SQLite--C语言接口规范(四) —— Result Values From A Query

数据库的在上一篇博客中<SQLite之C语言接口规范(三)——Binding Values To Prepared Statements>用到了如何从查询结果中取出结果值.今天的博客就详细的介绍一下sqlite3_column_*()的方法.在SQLite数据库C语言接口中,从查询结果中取出不同类型的值需要不同的接口函数. 一. sqlite3_column_*()介绍 1.下图是sqlite3_column_*()所包含的方法,由下图容易的看出取出不同类型的值需要不同的接口函数.可以取出的类