复习(一)

 

2014校招马上开始了,开始做准备工作,复习下C语言和数据结构、算法。废话少说,开始。

一、C语言核心知识复习

C语言核心为指针和内存管理,以及关键语法。

1 内存管理

1.1C语言内存空间

关键字:虚拟内存

出处:http://blog.csdn.net/wind19/article/details/5964090

 

C语言的内存主要有五个部分组成:代码段(.text)、数据段(.data)、BSS段(.bss),堆(heap)和栈(stack);

text段(程序代码区):存储程序代码

data段(静态存储区):存放编译阶段能确定的数据。已初始化的全局变量和静态变量,常量,有只读区和读写区。字符串存于只读区

BSS段:未初始化的全局变量和静态变量,默认设置为0,统一存放这类变量,省空间

堆:由程序员动态分配和释放。大小不固定,可以扩展和收缩

栈:编译器自动分配,临时创建,局部变量

1.2 分配方式

1、  从静态存储区分配,编译期就已经分配好了,整个运行期都在。全局变量,static变量,常量。

2、  栈上创建。局部变量定义时创建,执行结束自动释放。栈内存分配运算内置于处理器中。

3、  堆上分配。可动态内存分配。程序运行时调用malloc申请空间。需要手动free释放内存。这都是有程序员决定。

1.3 动态分配内存

出处:http://www.cnblogs.com/BlueTzar/articles/1136549.html

分配内存的函数有,malloc,calloc,realloc

这些函数从堆内存中获取空间。

三个函数的申明分别是: 
void* malloc(unsigned size); 分配size大小的空间;

void* calloc(size_t numElements, size_t sizeOfElement); 分配num个Element大小的空间;

void* realloc(void* ptr, unsigned newsize); 给已经分配空间的ptr再次分配一个大小为newsize的内存。

 

注意:

1、  分配空间之后,一定要检查是否分配成功,然后再做操作。

2、  再不用该内存空间之后,要free,释放资源,免得内存泄露。

1.4 分配堆内存的原理

出处:http://blog.csdn.net/jiaxiongxu/article/details/6613315

在回收和分配时,都只返回了一个指针,如何管理这些内存的?

内存来自于虚拟内存的映射,此时的资源无法使用,不可读。Sbrk函数用来获取从虚拟内存映射的内存,这些内存可以供malloc等函数调用,将其动态分配。

在从虚拟机映射过来的内存被用于动态分配时,即调用malloc函数时,有一个数据结构标记头在管理这段已分配的内存。

  1. struct mem_block_tag {  
  2.     int is_available;                   //标记此空间是否正在被利用  
  3.     size_t size;                        //此空间的大小  
  4. };

         该结构所在位置的末尾下个位置就是malloc函数返回的指针指向的位置。

        

因此用户可以直接按照普通的指针操作直接操作这段空间。当申请指定大小的空间时,系统将检测这些标记头的size字段,看大小是否大于指定空间。如果符合条件就将is_available设置为可用。如果没有合适的空间,将调用sbrk函数去申请新的 内存

         在free时,只需要将is_available设置为不可用。

  1. void free(void *ptr)  
  2. {  
  3.     struct mem_block_tag *pTag;  
  4.     pTag = ptr - sizeof(struct mem_block_tag); //找到标记头  
  5.     pTag->is_available = 1;                    //将空间标记为未使用,就等于告诉malloc这个内存空间不再使用了,可以分配给其他变量咯  
  1. }  

1.5 内存操作

出处:http://weishi2007.blog.163.com/blog/static/20417950201272651852433/

 #include <string.h>   #include <stdlib.h>

 

extern void *memcpy(void *dest, void *src, unsigned int count);

由src所指内存区域复制count个字节到dest所指内存区域。  

说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度


extern void *memset(void *buffer, int c, int count);

把buffer所指内存区域的前count个字节设置成字符c.说明:返回指向buffer的指针。

 

void * memmove ( void * destination, const void * source, size_t num );

将以source作为起始地址的数据的num个字节移动到以destination为起始地址的数据中,支持destination和source重叠的情况。函数返回destination指针。

 

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

比较以ptr1为起始地址数据和以ptr2为起始地址的数据的num个字节大小情况。如果num个字节都相等,则相等,函数返回0。从起始位置开始,如果某个字节大,则prt1>ptr2,函数返回正数,否则ptr<ptr2,函数返回负数。

void * memchr (void * ptr, int value, size_t num ); 

功能:在以ptr作为起始地址的数据中的num个字节中查找value,如果查到,则返回value所在的地址,否则返回NULL。

2 指针(下一章节再总结)

posted @ 2014-08-22 14:00  longstreet  阅读(161)  评论(0)    收藏  举报