您的位置:首页 > 编程语言 > C语言/C++

C语言基础知识整理16动态内存分配与指向它的指针变量

2019-02-14 11:33 274 查看

动态内存分配与指向它的指针变量

内存动态分配

c语言还允许建立内存动态分配区域,以存放临时用的数据,这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是需要时随时开辟,不需要时随时释放。

这些数据是临时存放在一个特别的自由区,称为堆区

堆可以根据需要向系统申请所需大小的空间。由于未在声明部分定义其为变量或数组,因此只能通过指针引用。

建立内存动态分配malloc,calloc,free,realloc

对内存的动态分配是通过系统提供的库函数实现的,主要有malloc,calloc,free,realloc四个函数。

//主要用于建立程序中的动态数据结构(如链表)

建立内存动态分配四大函数(malloc,calloc,free,realloc)

 

  • malloc 原型:void *malloc(unsigned int size);//作用是在内存的动态存储区中分配一个长度为size的连续空间。返回值是所分配区域的第一个字节的地址(函数为指针型函数,返回的指针指向分配域开头位置)。

//指针基类型为void,不指向任何类型数据,只提供一个地址。若函数无法成功执行(如内存空间不足),则返回空指针(NULL)

  • calloc 原型:void *calloc(unsigned n,unsigned size);//作用是在内存的动态存储区中分配n个长度为size的连续空间,这空间一般比较大,足以保存一个数组

//用此函数存放一维数组就是动态数组。返回起始地址指针,分配不成功返回NULL

  • free   原型:void free(void *p);//作用是释放指针变量p所指向的动态空间,使这部分空间能重新被其他变量使用。p是最近一次调用calloc或malloc函数时得到的返回值

//free函数无返回值

  • realloc原型:void *realloc(void *p,unsigned int size);//作用重新分配动态空间大小,将p所指向的动态空间大小改变为size。p值不变,若不成功返回NULL

这四个函数声明在stdlib.h中

 

以往c语言提供的malloc和calloc是指向字符型的指针。要用来存放整型数据需要进行类型转换(int*)。C99标准将其定为void类型,无类型指针,即不指向哪一种具体类型,只表示用来指向一个抽象的类型的数据,即仅提供纯地址,而不能指向任何具体对象。

 

void指针类型

C99允许使用基类型为void的指针类型。可以定义一个基类型为void的指针变量(即void*型变量),它不指向任何类型的数据。

//不要把“指向void类型”理解为能指向“任何的类型”的数据,而应理解为“指向空类型”或“不指向确定的类型”的数据。

//把void指针赋值给不同基类型的指针变量(或相反)时,编译系统会自动进行转换,不必用户自己进行强制转换。

         如int a=3;void *p;p=&a;(p=&a;相当于p=(void*)&a)  printf(“%d”,*p);//错误,赋值后p得到a的纯地址,但p是无指向的,不指向a,不能通过它输出a的值

 

小结

  1. 首先要准确地弄清楚指针地含义:指针就是地址。指针与指针变量区别:指针就是地址本身,指针变量是用来存放地址的变量,指针变量的值是一个地址。地址就是地址,本身就是一个值。
  2. 指向:地址就意味着指向,因为通过地址能找到具有该地址的对象。对于指针变量来说,把谁的地址存放在指针变量中,就说此指针变量指向谁。注意:只有基类型相同的数据的地址才能存放在相应的指针变量中。void*指针是一种特殊的指针,不指向任何类型的数据,如果需要用此地址指向某类型的数据,应先对地址进行类型转换。可以显式转换,也可系统自动进行隐式转换。
  3. 要深入掌握在对数组的操作中正确地使用指针,搞清楚指针地指向。一维数组名代表数组首元素的地址。
  4. 有关指针变量的归纳比较

指针变量的类型及含义

变量定义

类型表示

含义

int i

int

定义整型变量i

int *p

int *

定义p为指向整型数据的指针变量

int a[5]

int [5]

定义整型数组a,它有5个元素

int * p[4]

int *[4]

定义指针数组p,它由4个指向整型数据的指针元素组成

int (*p)[4]

int (*)[4]

p为指向包含4个元素的一维数组的指针变量

int f()

int ()

f为返回整型函数值的函数

int *p()

int *()

p为返回一个指针的函数,该指针指向整型数据

int (*p)()

int (*)()

p为指向函数的指针,该函数返回一个整型值

int **p

int **

p是一个指针变量,它指向一个指向整型数据的指针变量

void *p

void *

p是一个指针变量,基类型为void,不指向具体的对象

 

  1. 指针运算
  1. 指针变量加减一个整数:将该指针变量的原值(一个地址)和它指向的变量所占用的存储单元的字节数相加减。
  2. 指针变量赋值:将一个变量地址赋给一个指针变量。//不应把整数赋给指针变量
  3. 两个指针变量可以相减:当指向同一个数组的元素,差为两指针间的元素个数
  4. 两个指针变量比较:指向同一数组,指向数组前面的小于后面的
  1. 指针变量可以有空值,即该指针变量不指向任何元素,可以表示为:

p=NULL;//NULL是一个符号常量,代表整数0.在stdio.h中定义#define NULL 0

//它使p指向地址为0的单元。系统保证使该单元不作它用(不存放有效数据)。

//p的值为NULL与未对p赋值不同:前者是有值的(值为0),不指向任何变量,后者虽为对p赋值但不等于p无值,只是它的值是一个无法预料的值。(这种情况很危险,因此在引用指针变量之前应对它赋值)。

//任何指针变量或地址都可以与NULL作相等或不相等的比较。

使用指针的优点1.提高程序效率;2.在调用函数时当指针指向的变量的值改变时,这些值能够为主调函数使用,即可以从函数调用得到多个可改变的值;可以实现动态存储分配。

使用指针应当谨慎!!!!!!!!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: