黑马程序员技术交流社区

标题: iOS开发之 C语言变量\指针\函数\内存 [打印本页]

作者: FFFF001    时间: 2016-8-7 13:26
标题: iOS开发之 C语言变量\指针\函数\内存
#if 0
一个由C编译的程序占用的内存分为以下几个部分:

1. "栈区"(stack)-由"编译器自动"分配释放,存放"函数的参数值"、"局部变量"的值等

2. "堆区"(heap)-一般由"程序员分配"&&"释放",若程序员"不释放",程序"结束时可能由OS回收"。

3. "全局区"(静态区)(static)-全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS段)。程序结束后由系统释放。
4. "文字常量区"-常量字符串就是放在这里的。程序结束后由系统释放。
5. "程序代码区"-存放"函数体"的二进制代码。
#endif

#import <Foundation/Foundation.h>
#import <stdlib.h>

#pragma mark - 变量

int  a;
/*
*  类型: int
*      a是一个int类型的变量.
*/

int * p;
/*
*  类型: int *
*      p是一个int类型的指针. int *
*/
#if 0
* 从上面可以看出 "带星"的变量叫"指针", "不带星"的还是叫"变量"....都是变量,"叫法变了"
* 从上面可以看出 "带星"的变量叫"指针", "不带星"的还是叫"变量"....都是变量,"叫法变了"
* 从上面可以看出 "带星"的变量叫"指针", "不带星"的还是叫"变量"....都是变量,"叫法变了"
#endif

#pragma mark - 函数

#if 0
!!!!!!!!!!!!!!!!!!所有"函数","左边"的"类型"是"返回值的类型"!!!!!!!!!!!!!!!!
#endif

/*
*  普通函数
*/
int test();
/*
*  类型: int ()
*      第一步: (), 说明test是一个函数. ()
*      第二步: int (), test的返回值为 int 类型. int
*      连起来就是: test是一个函数,他的返回值的类型是int类型.
*/

#if 0
!!!!!!!!!!!!!!!!!!所有"函数","左边"的"类型"是"返回值的类型"!!!!!!!!!!!!!!!!
#endif
/*
* 返回值为指针的函数
*/
int *pFun();
/*
*  类型: int * ()
*      第一步: 括号()的优先级比*高,先 (), 说明pFun是一个函数. ()
*      第二步: int * (),说明pFun的返回值是一个int类型的指针(记住:左边类型为函数返回值类型). int *
*      连起来就是: pFun是一个函数,他的返回值是一个int类型的指针
*/


#if 0
!!!!!!!!!!!!!!!!!!所有"函数","左边"的"类型"是"返回值的类型"!!!!!!!!!!!!!!!!
#endif
/**
*  指向函数的指针
*/
int (*funP)();
/*
*  类型: int (*) ()
*      第一步: (*), 说明funP是一个指针. *
*      第二步: int (*)(), 说明funP指向了一个返回值是int类型的函数. int ()
*      连起来: funP是一个指针,他指向了一个返回值是int类型的函数
*/


#pragma mark - 栈分配内存从高地址向低地址分配
int *pFun() {
   
// p1 先入栈.  malloc会在堆上开辟空间,将地址存在 p1 中.(p1在栈上有8个字节,里面存的是地址)
    int *p1 = malloc(sizeof(int));
   
// p2 后入栈.
    int *p2 = malloc(sizeof(int));
   
// p2自己的地址减去p1自己的地址.
    printf("%ld\n", &p2 - &p1);     // 结果 -1 ,说明栈分配内存从高到低
   
    printf("p1 = %p\n", &p1);       // &p1为p1自己在栈上的地址
   
    printf("p2 = %p\n", &p2);       // &p2为p2自己的地址
   
   
// **** 还有 指针类型不同(虽然都占8个字节),不可相减
    char *p3 = malloc(sizeof(char));
   

//    printf("%d\n", &p3 - &p2);    // ******* 不可以相减,报错
   
    free(p1);
    free(p2);
    free(p3);
   
    return 0;
}

#pragma mark - 栈,堆 的内存分配
void testFun() {
   
    int a;                  // a在栈区. 局部变量,出了这个函数就会释放.
   
    static int b;           // b 在全局(静态)区. static修饰.
   
    char *str = "abcd";     // str 自己在栈区,指向常量区. abcd\0 在常量区
   
    char *p = malloc(8);    // p 自己在栈区,指向堆区.分配来的8个字节在堆区
   
                    // a, str, p 均是局部变量,出了这个函数就会释放死掉.
   
                    // b 由于 static修饰,会分配到全局区,所以下次进来这个函数,他还在.
                    // b 直到程序结束才会释放
   
    printf("%d%d%s%s", a, b, str, p);
}

#pragma mark - main
int main(int argc, const char * argv[]) {
   
    pFun();
   
    return 0;
}




作者: 风不会停息    时间: 2016-8-9 23:23
顶顶顶~~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2