学习 Linux高级编程02

DAY02AM

 

回顾:

         brk/sbrk

         intbrk(void *p)

         void*sbrk(int);

         补充:全新的类型。

                   永远记住:C的基本类型就:整数(1.char2.short 4.int)、小数(4.float 8.double)

                   所有全新类型都是使用typedef重新定义的。

                   新的类型的C的原型。

                   类型重定义的好处:1.维护方便 2.移植 3.容易理解

         维护一个位置。brk/sbrk改变这个位置

                   brk改变绝对位置

                   *sbrk相对改变位置

                  

一、映射虚拟内存

         没有任何额外维护数据的内存分配。

         mmap(分配)/ munmap(释放)

         1.函数说明

                   manmmap

                   void*mmap(

                            void*start,  //指定映射的虚拟地址 ,0由系统指定开始位置

                            size_tlength, //映射空间大小,pagesize倍数

                            intprot, //映射的权限 PROT_NONE PROT_READ PROT_WRITE PROT_EXEC

                            intfalgs, //映射的方式

                            intfd, //文件描述符

                            off_t_toffset); //文件中的映射开始位置,pagesize倍数

                   映射方式:

                            内存映射:(匿名映射)

                            文件映射:映射到文件。

                                              只有文件映射最后两个参数才有效,否则无效。

                            MAP_ANONYMOUS//内存映射方式 (/不选)

                            MAP_SHAREDMAP_PRIVATE (二选一)

                   size_tlength //4k*(length/4k +1)

                   intprot      //权限只有三种读\\执行

                   off_t_toffset  //必须是4k的整倍数

                  

                   intmunmap(void *start, size_t length);

         2.案例

         3.总结

                   选择什么样的内存管理方法?

                            智能指针(指针池) --ObjectC

                            STL

                            new                          

                            malloc(小而多数据)

                            brk/sbrk(同类型的大块数据,动态移动指针)

                            mmap/munmap(1.控制内存访问 2.使用文件映射 3控制内存共享(父子进程之间))

                           

                            C++用的是 STL, new()

                            最方便的是 STL new

                            效率最高的、数组最快的是brk/sbrk mmap/munmap

                           

         4.应用

        

二、编程工具与动态库

         1.gcc

                   -o输出文件名

                   -O-O0 -O1 -O2 -O3编译优化

                   -g-g0 -g1 -g2 -g3产生调试信息

                   -W-all  error //把空格省掉就是 -Wall显示所有警告 -Werror把警告当作错误

                  

                   -o关闭所有警告

                   -c只编译不连接

                   -E预编译 //gcc map.c -E -o -map.i

                   -S汇编   //gcc map.c -S //生成map.s文件

                   -D在命令行定义宏

                                    在代码中定义宏

                                    在命令行定义宏

                   -x指定编译的语言类型  //gcc -x assembler maps.s

                            c++

                            c

                            .S

                            none自动判定

                   -std=c89

                             c99

                  

                  

                   编译过程 -E -c -S//自动调用连接器

                   连接器   ld //ld map.s | ld map.o

                  

                   补充:

                            .c   :C

                            .cpp:C++

                            .CC  :C++

                            .h   :头文件

                            .hppC++头文件

                            .o  :目标文件

                            .a

                            .so :共享目标文件、动态库

                            .i  :预编译文件

                            .s  :汇编文件

                   产生预编译文件

                   gccmap.c -E -o map.i

                   catmap.i

         2.其他工具

         3.共享库

         4.make

         5.gdb

 

三、静态库的编译

         1.编译过程(*.aachieve)

                   1.1.编译成目标文件

                            -static//可选

                            gcc-c -static代码文件.c

                   1.2.归档成静态库

                            ar工具

                                     ar     -r

                                               -t

                                               -p

                                               -x

                                               -m

                                               -q

                                     ar-r静态库文件被归档的名称[列表]

                                     ar-t查看库中含有那几个文件

                            nm工具(查看函数符号表)

                                     nm静态库、动态库、目标文件、执行文件

                   1.3.使用静态库

                            gcc代码静态库

         使用静态库完成如下程序:

                   输入一个菱形半径,打印菱形

                   输入整数封装成IOTool

                   菱形的打印封装成Graphics

                   计划:

                            1.实现输入

                            2.实现菱形

                            3.编译静态库

                            4.调用静态库

                           

四、动态库的编译

 

 

代码map.c

#include<stdio.h>

#include<sys/mman.h>

#include<stdlib.h> //NULL

#include<stdio.h>

int main()

{

         int  *p = mmap(

                   NULL,

                   getpagesize(),  //返回基本单位

                   PROT_READ  | PROT_WRITE, //如果只有PROT_READ就会返回段错误

                   MAP_ANONYMOUS  | MAP_SHARED,

                   0,0);

        

         *p  = 20;

         *(p+1)  = 30;

         *(p+2)  = 40;

        

         printf("%d\n",  p[2]);

}

执行结果:

PROT_READ,//如果只有PROT_READ就会返回段错误

释放内存 munmap函数调用

#include<stdio.h>

#include<sys/mman.h>

#include<stdlib.h> //NULL

#include<stdio.h>

int main()

{

         int  *p = mmap(

                   NULL,

                   getpagesize(),  //返回基本单位

                   PROT_READ  | PROT_WRITE, //如果只有PROT_READ就会返回段错误

                   MAP_ANONYMOUS  | MAP_SHARED,

                   0,0);

        

         *p  = 20;

         *(p+1)  = 30;

         *(p+2)  = 40;

        

         printf("%d\n",  p[2]);

        

         munmap(p,  4096);

}

 

编译优化测试

默认情况下产生的文件大小

-O0

-O1

-O2

-O3

 

产生调试信息测试

默认情况下产生的文件大小

-g0

-g1

-g2

-g3

 

int printf(const char*,...);

int add(int * restrict a, int * restrict  b)

{

         return  (*a) + (*b);

}

 

main()

{

         for(int  i = 0; i < 100; i ++)

         {

                   printf("%d\n",  NUM);

         }

}

-std89 不支持 restrict

-std99 支持   restrict

 

 

Ku1.c

int add(int a, int b)

{

         return  a + b;

}

Ku2.c

int sub(int a, int b)

{

         return  a - b;

}

Callku.c

main()

{

         int  r = add(45, 55);

         int  s = sub(100, 45);

}

Gcc callku.c ku1.c ku2.c –ocallku //不用库的方式,库的好处可以减小文件的大小

编译成目标文件

ar -r 静态库文件被归档的名称[列表]

ar -t 查看库中含有那几个文件

ar -p

nm工具nm ku.a

使用静态库

 

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");

         }       

}

T 自己实现的函数

U 外部库引用的函数

 

 

 

你可能感兴趣的:(学习 Linux高级编程02)