• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0
            brk/sbrk
            維護一個位置。 brk/sbrk改變這個位置。
            brk改變絕對位置
            sbrk改變相對位置

            昨天的補充:
            永遠記住:C的基本類型就那幾種。
            所有全新類型都是使用typedef重新定義的。
            類型重定義的好處:
            1. 維護方便
            2. 便于移植(每個系統中都用同一個名,不用修改)
            3. 容易理解

            一、 映射虛擬內存
            沒有任何額外維護數據的內存分配 mmap/munmap
            1. 函數說明:

            void *mmap(
            void *start, //指定映射的虛擬地址,如果為0,則由系統指定開始位置
            size_t length,//指定映射空間的大小。 pagesize的倍數
            int prot, //映射的權限 PROT_NONE PROT_READ PROT_WRITE PROT_WRITE PROT_EXEC
            int flags, //映射的方式
            int fd, //文件描述符號
            offset_t off //文件中的映射開始位置(必須是0或pagesezi的倍數)
            );

            關于映射的方式flags:
            內存映射:又叫匿名映射,最后兩個參數無效
            文件映射:映射到某個文件
            只有文件映射,最后兩個參數才有效
            MAP_ANONYMOUS:內存映射
            MAP_SHAREDMAP_PRIVATE:二選一,文件映射

            2. 案例:

            #include <unistd.h>
            #include <sys/mman.h>
            #include <stdlib.h>
            #include <stdio.h>

            int main()
            {
            int *p = mmap(
            NULL,
            getpagesize(),
            PROT_READ|PROT_WRITE,
            MAP_ANONYMOUS|MAP_SHARED,
            0,
            0);
            *P = 20;
            *(p+1) = 30;
            *(p+2) = 40;
            printf("%d\n", p[2]); //打印出40
            munmap(p, 4096);
            }
            3. 總結:
            選擇什么樣的內存管理方法?
            STL
            new

            malloc小而多的數據
            brk/sbrk同類型的大塊數據,動態移動指針
            mmap/munmap 控制內存的訪問/使用文件映射/控制內存共享

            二、編程工具與動態庫
            1. gcc
            2. make
            3. gdb
            4. 其他工具
            5. 動態庫(共享庫)

            1. gcc
                -o 輸出文件名
                -O-O1-O2-O3//編譯優化
                -g-g1-g2-g3//產生調試信息 
                -Wallerror//-Wall 顯示所有警告-Werror 將警告當成錯誤提示
                -w//關閉所有警告
                -c//只編譯不連接,產生 .o文件(目標文件)
                -E//預編譯
                -S//匯編。 產生 .s文件(匯編文件)

            編譯4過程是 -E(產生.i) -c(產生.o) -S(產生.s) 自動調用連接器ld

                -D//在命令行定義宏 (宏可以在代碼中定義,也可以在命令行上定義)
                -x//指定編譯的語言類型 C, C++, .S(匯編), none(自動判定)
                -std=c89  使用標準C89
                -std=c99  使用標準C99

            三、 靜態庫的編譯
            1. 編譯過程 (*.a) a是achieve的縮寫
              1.1 編譯成目標文件
                -static 可選
                gcc -c -static 代碼文件.c  //生產可用于歸檔的目標代碼:代碼文件.0
              1.2 歸檔成靜態庫
                ar工具 (常用-r -t選項)
                ar -r 靜態庫 被歸檔的文件名(上一步代碼文件.o) 
                ar -r add.a add.o
                nm工具(查看庫中所蘊含的函數列表)
                nm 靜態庫或動態庫或目標文件或執行文件
              1.3 使用靜態庫
                gcc 代碼文件 靜態庫
            小例子:
            使用靜態庫完成如下程序
            輸入一個菱形半徑,打印菱形
            輸入整型封裝成IOTool
            菱形打印封裝成Graphic
            計劃:
            1. 實現輸入
            2. 實現菱形
            3. 編譯靜態庫
            4. 調用靜態庫

            //iotool.c
            #include <stdio.h>
            int inputInt(const char *info)
            {
            int r; //返回值
            printf("%s:", info);
            scanf("%d", &r);
            return r;
            }
            //graphic.c
            #include <stdio.h>
            void diamond(int r)
            {
            int x, y;
            for(y=0; y<=2*r; y++)
            {
            for(x=0; x<=2*r; x++)
            {
            if(y == x+r || y == x-r ||y == -x+r || y == -x+3*r)
            {
            printf("*");
            }
            else
            {
            printf(" ");
            }
            }
            printf("\n");

            }
            }

            編譯: gcc -c -static iotool.c

            gcc -c -static graphic.c
            ar -r demo1.a iotool.o graphic.o
            ar -t demo1.a //相當于nm demo1.a

            //main.c
            main()
            {
            int r = inputInt("輸入菱形半徑:");
            diamond(r);
            }

            編譯: gcc main.c demo1.a -o main

            執行:./main
            把靜態庫作為代碼的一部分來編譯

            總結:
            1. 什么是庫?
            函數等代碼封裝的二進制已經編譯的歸檔文件
            2. ar歸檔工具
            3. 采用庫的方式管理代碼優點:
            容易組織代碼
            復用
            保護代碼版權
            4. 靜態庫的“靜態”的含義:
            編譯好的程序運行的時候不依賴庫
            庫作為程序的一部分編譯連接
            5. 靜態庫的本質
            就是目標文件的集合(歸檔)
            6. -static可選

            2. 庫的規范與約定
            庫命名規則:
            lib庫名.a.主版本號.副版本號.批號
            一般就寫“lib庫名.a”就行了。
            ar -r libdemo2.a iotool.o graphic.o
            庫的使用規則
            -l庫名
            -L庫所在的目錄
            gcc main.c -o main -l demo2 -L.

            四、 動態庫的編譯
            1. 什么是動態庫(共享庫)
            動態庫是可以執行的,靜態庫不能執行
            但動態庫沒有main,不能獨立執行
            動態庫不會連接成程序的一部分
            程序執行時,必須需要動態庫文件
            2. 工具
            ldd查看程序需要調用的動態庫 ,ldd只能查看可執行文件(共享庫文件或elf文件)
            nm (查看庫中的函數符號)
            3. 動態庫的編譯
            3.1編譯
            -c -f pic(可選) (-f 指定文件格式 pic 位置無關代碼)
            3.2 連接
            -shared

            編譯:gcc -c -fpic iotool.c
            gcc -c -fpic graphic.c
            (非標準)gcc -shared -odemo3.so iotool.o graphic.o
            (標準)gcc -shared -olibdemo4.so iotool.o graphic.o
            4. 使用動態庫
            gcc 代碼文件名 動態庫文件名
            gcc 代碼文件名 -l庫名 -L動態庫所在的路徑
            gcc main.c -ldemo4 -L. -o main

            標準命名規則:
            lib庫名.so
            lib庫名.a

            問題:
            4.1 執行程序怎么加載動態庫?
            4.2 動態庫沒有作為執行程序的一部分,為什么連接需要制定動態庫及目錄?
            因為連接器需要確認函數在動態庫中的位置
            動態庫的加載:
            1. 找到動態庫
            2. 加載動態庫到內存(系統實現)
            3. 映射到用戶的內存空間(系統實現)
            動態庫查找規則:
            /lib
            /user/lib
            LD_LIBRARY_PATH環境變量指定的路徑中找
            設置當前路徑為環境變量:(自己定義的庫最好設置好目錄,或者放到上述公共目錄)
            export LD_LIBRARY_PATH=.:~:..:~Walle
            緩沖機制:
            系統把lib:/user/lib:LD_LIBRARY_PATH里的文件加載到緩沖
            /sbin/ldconfig -v 刷新緩沖so中的搜索庫的路徑
            小練習:
            輸入兩個數,計算兩個數的和。
            要求:輸入與計算兩個數的和封裝成動態庫調用

            五、 使用libdl.so庫
            動態庫加載原理
            動態庫中函數的查找已經封裝成哭libdl.so
            libdl.so里面有4個函數:
            dlopen//打開一個動態庫
            dlsym//在打開的動態庫里找一個函數
            dlclose//關閉動態庫
            dlerror//返回錯誤


            //dldemo.c
            #include <dlfcn.h>
            main()
            {
            void *handle = dlopen("./libdemo4.so", RTLD_LAZY);
            void (*fun)(int) = dlsym(handle, "diamond");
            fun(5);
            dlclose(handle);
            }
            gcc dldemo.c -o main -ldl

            ldd main
            ./main

            總結:
            1. 編譯連接動態庫
            2. 使用動態庫
            3. 怎么配置讓程序調用動態庫
            4. 掌握某些工具的使用 nm ldd lddconfig objdump strit(去掉多余的信息)

            六、 工具make的使用與makefile腳本
            背景:
            make編譯腳本解釋
            編譯腳本makefile
            make -f 腳本文件 目標
            腳本文件:
            1. 文本文件 (例如 demo.mk)
            2. 基本構成語法
            基本單位目標target
            目標名:依賴目標
            \t目標指令
            \t目標指令

            //demo.mk
            demo:iotool.c graphic.c main.c
            gcc iotool.c -c
            gcc graphic.c -c
            gcc iotool.o graphic.o -shared -o libdemo.so
            gcc main.c -ldemo -L. -o main
            make -f demo.mk demo 會生產main可執行文件
            国内精品久久久久影院老司| 久久棈精品久久久久久噜噜| 99久久99久久精品免费看蜜桃 | 久久国产高清字幕中文| 99久久99久久精品国产| 久久九九久精品国产免费直播| 国产精品久久久久久| 久久婷婷五月综合97色直播| 91视频国产91久久久| 久久无码AV中文出轨人妻| 亚洲国产另类久久久精品黑人| 国产综合精品久久亚洲| 国产精品久久网| 久久无码AV一区二区三区| 日韩欧美亚洲综合久久影院d3| 久久久精品国产sm调教网站| 久久久久久久国产免费看| 国产精品欧美久久久久无广告 | 日韩精品久久久久久免费| 亚洲精品午夜国产va久久| 国产精品久久久天天影视香蕉| 色诱久久久久综合网ywww| 国内精品久久国产| 亚洲精品综合久久| 三级片免费观看久久| 久久男人AV资源网站| 国产精品九九久久免费视频| 久久国产热精品波多野结衣AV| 久久亚洲精品无码aⅴ大香 | 亚洲国产精品无码久久一线| 久久久久亚洲AV无码专区网站| 久久国产亚洲精品无码| 久久精品二区| 99久久国产亚洲高清观看2024| 亚洲AV无一区二区三区久久 | 青青青伊人色综合久久| 热re99久久6国产精品免费| 亚洲乱码精品久久久久..| 亚洲精品乱码久久久久久蜜桃图片 | 国产精品99久久久久久宅男| 国产成人精品久久一区二区三区|