C 基本了解

Linux內(nèi)存單位

image.png

image.png

image.png

image.png
  • 棧區(qū):占用內(nèi)存大小 最大值: 大概 2M 大于2M會(huì)棧溢出 平臺(tái)有關(guān)系的
  • 堆區(qū):占用內(nèi)存大小 最大值: 大概80% 40M沒(méi)有任何問(wèn)題,基本上不用擔(dān)心 堆區(qū)很大的

// malloc 在堆區(qū)開(kāi)辟的內(nèi)存空間 , (動(dòng)態(tài)的范疇) ,C的開(kāi)發(fā)過(guò)程中,不能出現(xiàn),野指針,懸空指針
void dynamicAction() {
    int * p; // 野指針  沒(méi)有地址的,空的
    // void * 可以任意轉(zhuǎn)變   int*  double *
    int * arr = malloc(4 * 1024 * 1024); // 1024x1024字節(jié),堆區(qū)開(kāi)辟 4M
    printf("dynamicAction函數(shù),arr自己的內(nèi)存地址:%p,堆區(qū)開(kāi)辟的內(nèi)存地址:%p\n", &arr, arr);
    // C工程師,堆區(qū)開(kāi)辟的空間,必須釋放
    free(arr); // 釋放掉
    arr = NULL; // 重新指向一塊內(nèi)存地址00000
    printf("dynamicAction函數(shù)2 堆區(qū)開(kāi)辟的內(nèi)存地址:%p\n", arr); // 懸空指針
}
// 字符串
int mainT2() {
    char str[] = {'D', 'e', 'r', 'r', 'y', '\0'};
    str[2] = 'z'; // 這里能修改?
    printf("第一種方式:%s\n", str); // printf 必須遇到 \0 才結(jié)束

    char * str2 = "Derry"; // 隱士  Derry+\0
    str2[2] = 'z'; // 會(huì)奔潰
    printf("第二種方式:%s\n", str);

    return 0;
}

C運(yùn)行單位

  • C是以函數(shù)作為基本單元,并且從上往下進(jìn)行執(zhí)行,所以函數(shù)A調(diào)用函數(shù)B的時(shí)候需要先將函數(shù)B寫(xiě)在函數(shù)A前面,為了方便開(kāi)發(fā)所以出現(xiàn)了頭文件進(jìn)行函數(shù)聲明,然后在實(shí)現(xiàn),這樣可以先引入聲明文件就可以不用區(qū)分函數(shù)的先后順序。
  • JAVA 是以類(lèi)作為基本單位進(jìn)行編輯,所以在類(lèi)里面函數(shù)不分先后都可以找到并執(zhí)行。

指針

  • 指針是存放對(duì)應(yīng)變量的地址,可以通過(guò)指針在改變變量的值
  • 指針優(yōu)先級(jí) ()> [] > *

指針函數(shù) 函數(shù)指針

  • 指針函數(shù)就是返回值為指針的函數(shù)。
  • 函數(shù)指針是聲明函數(shù)類(lèi)型的變量,可以將對(duì)應(yīng)的函數(shù)賦值給這個(gè)變量。
image.png

image.png

數(shù)組

  • 可以用一個(gè)指針指向數(shù)組首地址,這樣可以通過(guò)指針操作數(shù)組,數(shù)組的內(nèi)存地址 == 第一個(gè)元素的內(nèi)存地址 == &arr
image.png

image.png

image.png

指針數(shù)組

數(shù)組的每個(gè)元素存放的都是指針


image.png

數(shù)組指針

數(shù)組指針一般是行指針,實(shí)質(zhì)上可以用做表示多維數(shù)組


image.png

共用體

image.png

共用體的內(nèi)存占用是根據(jù)成員里面最長(zhǎng)的那個(gè)決定的,而結(jié)構(gòu)體是多個(gè)成員加起來(lái)的總和

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

結(jié)構(gòu)體

  • 將多個(gè)變量封裝成一組稱(chēng)為結(jié)構(gòu)體
  • 結(jié)構(gòu)體聲明后可以不用像java那樣實(shí)例化,可以直接使用 + 給結(jié)構(gòu)體分配內(nèi)存的時(shí)候是遵循內(nèi)存對(duì)齊的規(guī)則(因?yàn)椴挥脙?nèi)存對(duì)齊,訪問(wèn)一個(gè)變量會(huì)訪問(wèn)兩次來(lái)拼湊一個(gè)完整有效數(shù)據(jù),為了提高執(zhí)行效率,所以用了內(nèi)存對(duì)齊,比結(jié)構(gòu)體中有 int 、short 兩個(gè)變量,實(shí)際上分配內(nèi)存為8個(gè)字節(jié)而不是6個(gè)字節(jié))


    image.png

    image.png

    image.png

    image.png
struct Cat {
    char name[10];
    int age;
};

int main() { // 棧

    // 結(jié)構(gòu)體
    struct Cat cat = {"小花貓", 2};
 
    // VS的寫(xiě)法: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的寫(xiě)法: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);

    // 堆區(qū)的必須釋放
    free(cat);
    cat = NULL;

    return 0;
}

struct Workder_ {
    char name[10];
    int age;
    char sex;
};

// VS的寫(xiě)法:typedef Workder_
typedef struct Workder_ Workder_; // 給結(jié)構(gòu)體取別名

typedef Workder_ * Workder; // 給結(jié)構(gòu)體指針取別名

// C庫(kù)的源碼,系統(tǒng)源碼...,為什么 typedef 還取一個(gè)和結(jié)構(gòu)體一樣的名字(兼容代碼的寫(xiě)法,保持一致)

int main() {
    // 以前 Clion工具 必須加上 struct   VS又不用加  代碼差異化大
    // struct Workder_ workder1 = malloc(sizeof(struct Workder_));

    // 現(xiàn)在 (兼容代碼的寫(xiě)法,保持一致)
    Workder_ workder1 = malloc(sizeof(Workder_));

    // VS  CLion  他們都是一樣的寫(xiě)法
    Workder workder = malloc(sizeof(Workder_));

    return 0;
}

庫(kù)文件(動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù))

image.png

image.png

image.png

image.png

APK 中一般用動(dòng)態(tài)庫(kù)比較多,考慮的主要是apk的大小

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容