美文网首页
C 基本了解

C 基本了解

作者: 内卷程序员 | 来源:发表于2022-12-26 16:09 被阅读0次

    Linux内存单位

    image.png
    image.png
    image.png
    image.png
    • 栈区:占用内存大小 最大值: 大概 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 是以类作为基本单位进行编辑,所以在类里面函数不分先后都可以找到并执行。

    指针

    • 指针是存放对应变量的地址,可以通过指针在改变变量的值
    • 指针优先级 ()> [] > *

    指针函数 函数指针

    • 指针函数就是返回值为指针的函数。
    • 函数指针是声明函数类型的变量,可以将对应的函数赋值给这个变量。
    image.png
    image.png

    数组

    • 可以用一个指针指向数组首地址,这样可以通过指针操作数组,数组的内存地址 == 第一个元素的内存地址 == &arr
    image.png
    image.png
    image.png

    指针数组

    数组的每个元素存放的都是指针


    image.png

    数组指针

    数组指针一般是行指针,实质上可以用做表示多维数组


    image.png

    共用体

    image.png

    共用体的内存占用是根据成员里面最长的那个决定的,而结构体是多个成员加起来的总和

    //共用体声明 
    union Data{
    int I;
    float f;
    char str[2];
    } data;
    
    image.png

    结构体

    • 将多个变量封装成一组称为结构体
    • 结构体声明后可以不用像java那样实例化,可以直接使用 + 给结构体分配内存的时候是遵循内存对齐的规则(因为不用内存对齐,访问一个变量会访问两次来拼凑一个完整有效数据,为了提高执行效率,所以用了内存对齐,比结构体中有 int 、short 两个变量,实际上分配内存为8个字节而不是6个字节)


      image.png
      image.png
      image.png
      image.png
    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;
    }
    

    库文件(动态库、静态库)

    image.png
    image.png
    image.png
    image.png

    APK 中一般用动态库比较多,考虑的主要是apk的大小

    相关文章

      网友评论

          本文标题:C 基本了解

          本文链接:https://www.haomeiwen.com/subject/dpyhortx.html