指针与内存管理

指针与内存管理

一、指针数组

指针 数组中的每一个元素均为指针,即有诸形如“*ptr_array[i]”的指针。
指针数组中的元素亦可以表示为“*(*(ptr_array+i))”。又因为“()”的优先级较“*”高,且“*”是右结合的,因此可以写作**(ptr_array+i)。
由于数组元素均为指针,因此ptr_array[i]是指第i+1个元素的指针。
运用:
指针 数组可以作为函数的参量使用,使用方式与普通数组类似。
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。

定义:由指针变量构成的数组,数组中的每个元素都是指针

例子:int *a[5];   a[0]就是一个整形指针变量

      char *a[5]={“welcome”,”to”,”beijing”,”happy”,””};

 

二、函数指针

函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。

方法:

函数指针的声明方法为:
返回值类型 ( *  指针变量名) ([ 形参列表]);
注1:“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:
int func(int x); /* 声明一个函数 */
int (*f) (int x); /* 声明一个函数指针 */
f=func; /* 将func函数的首地址赋给指针f */
或者使用下面的方法将函数地址赋给函数指针:
f = &func;
赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
注2: 函数括号中的 形参 可有可无,视情况而定

typedef:作用就是给数据类型起别名

格式:typedef  原类型名称  新名称;

 

typedef unsignedint uint;

unsigned inta;===>uint a;

 

优点:1、书写简洁,使用方便

      2、提高代码的可移植性

 

typedef longsize_t;   32

typedef intsize_t;      64

 

 

利用函数指针对数组进行排序:

 

 45 //冒泡排序(函数指针)

 46 #include<stdio.h>

 47 intcompare(int a, intb)

 48 {

 49         returna-b;

 50 }      

 51 voidsort(int *a, intn, int (*p)(int,int))

 52 {

 53         inti;

 54         for(i=0; i<n-1;i++) {

 55                 intj;

 56                 for(j=0; j<n-i-1;j++) {

 57                         if (p(a[j],a[j+1]) < 0) {

 58                                 int temp = a[j];

 59                                 a[j] = a[j+1];

 60                                 a[j+1] = temp;

 61                         }      

 62                 }      

 63         }      

 64 }      

 65

 66 intmain(int argc, char*argv[])

 67 {

 68         inta[] = {1,2,3,4,5};

 69         sort(a, 5,compare);

 70         inti;

 71         for(i=0; i<5;i++) {

 72                 printf("%d ",a[i]);

 73         }      

 74         printf("\n");

 75         return0;

 76 }      

 

 

 

 

三、静态内存管理

定义:在编译时确定大小,OS在合适(函数)调用的时候分配特点大小的空间,在函数调用结束的时候由操作系统统一释放。

 

优点:

1、由操作系统统一管理(分配、释放)

2、分配效率高。(节约时间)

3、无需人工参与,可靠性高,基本上不会失败。

缺点:

1、分配只能做到计划分配,会造成内存浪费

2、用完不能立即释放,会造成内存利用率降低

 

 

四、动态内管理

 

定义:在程序运行时,根据实际的需要确定大小,在需要的时候进行分配(程序的运行中)和内存释放。

优点:

1、节省内存,可以做到按需分配

2、内存使用率高,用完立即释放。

缺点:

1、需要手动参与与管理(申请、释放)

2、分配效率低;

3、分配空间可能会失败,需要判断内存申请是否成功,若失败需要做出错处理,否则可能会出现崩溃

 

 

手动参与会出现潜在的风险:

1、忘记释放一段内存,称为【内存泄露】

2、使用已经释放的内存,称为【提前释放内存】

3、多次释放同一内存,称其为【重复释放内存】

 

 

 

分配:malloc 

释放:free

 

 

1、动态内存分配在堆上。

2、其生命周期是从申请到释放;

3、作用域是能够访问到的地方。

 

 

  1 #include<stdio.h>

  2 #include<stdlib.h>

  3 intmain()

  4 {

  5         char*p=(char *)malloc(100);

  6         if(p==NULL)

  7         {

  8                 printf(失败\n);

  9         return-1;

 10         }

 11         gets(p);

 12         puts(p);

 13         free(p);

 14         return0;

 15 }

 

 

 

五、全局变量

定义:定义在函数外部的变量,也叫外部变量。(定义在全局区)

生命周期:整个程序

作用域:整个程序

 

优点:全局都可以访问,避免复杂的传参

缺点:

1、全局都可以修改,出错不易定位

2、增强了代码的耦合性

 

建议:尽量的少使用

大家还可以参照:C内存管理(是一片不错的文章)

http://www.360doc.com/content/13/0130/17/1200324_263271184.shtml


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值