C++小结--指针
1 指针
在C++中的指针用法和C语言中是一样的,我们要时刻理解并认识到,指针也是一种变量,它和普通变量是一样的,都是用来存放数据的。只不过指针变量存放的数据比较特殊,是内存地址。并且要注意:一般情况下,如果不考虑指针强制类型转换的话,我们要求某个类型的地址必须放到对应类型的指针变量中。
1.1 指针的定义和初始化
不管是在C语言还是C++语言中,指针在定义时都需要为其实例化,防止野指针的出现。我们定义一个指针的目的是为了用该指针指向特定的内存地址,所以在定义时,就需要为该指针分配好或者说是指定好特定的内存地址,如果没有指向,可以指到NULL。注意:在使用该指针前,一定要心里有数该指针指向了哪里,如果随意使用指针,有可能造成未知的系统错误,并且这些错误一般还不好发现。所以,养成良好的编程习惯非常重要。
1.2 在一个函数体中为什么需要使用指针
首先,在C语言中,我们使用malloc和free来分配和释放内存,在C++中,我们使用new和delete来分配和释放内存,同时malloc和free也是可以使用的。
为了尽可能少的使用栈区空间,我们通常定义一个指针变量,然后再为它分配内存空间,最后再使用它。举个例子:
int fun()
{
int temp[100] = {0};
int *p1 = NULL;
int *p2 = new int[100];
p1 = (int *)malloc(sizeof(int)*100);
free(p1);
delete [] p2;
return 0;
}
在上述例子中,三个变量temp p1 p2都是指向一个数组的首地址,不同的是,p1和p2占用的是堆内存,temp占用的是栈内存。当fun函数执行完毕后,temp占用的内存空间就会自动释放,而我们调用了delete和free也会同样释放p1和p2的内存空间。注意:在函数中为指针变量分配内存空间时,用完一定要记得释放,否则多次调用就会造成内存泄漏。
1.3 C++中指针的一般用法
我们直接通过一个实例来分析一下指针的具体用法。
#include <iostream> //输入输出流控制头文件
using namespace std; // 命名空间
int main()
{
int *p1 = new int; //申请内存
char *p2 = new char;
float *p3 = new float(12.34);
char *p4 = new char[100]; //申请数组
int *p5 = NULL;
char *p6 = NULL;
p6 = (char *)malloc(sizeof(char)*100);
int a = 100;
p5 = &a;
p4 = "hello world";
p6 = "你好,世界!";
*p1 = 124; //赋值
cout << *p1 << endl; //读
cout << *p3 << endl; //读
cout << p4 << endl;
cout << p6 << endl;
cout << *p5 << endl;
delete p1, p2, p3; //释放
delete [] p4;
free(p5);
free(p6);
system("pause");
return 0;
}
1.4 malloc和new的区别
我们前面说过malloc是c语言中用于动态分配内存,new是C++中用于动态分配内存。
在使用上,malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:
int *p;
p = new int; //返回类型为int *类型(整数型指针),分配大小为sizeof(int);
或:
int *parr;
parr = new int[100]; //返回类型为int *类型(整数型指针),分配大小为sizeof(int) * 100;
而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。
int *p;
p = (int*)malloc(sizeof(int) * 128);
//分配128个(可根据实际需要替换该数值)整型存储单元,
//并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd = (double*)malloc(sizeof(double) * 12);
//分配12个double型存储单元,
//并将首地址存储到指针变量pd中
第一、malloc 函数返回的是 void * 类型。
对于C++,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。
所以必须通过 (int *) 来将强制转换。而对于C,没有这个要求,但为了使C程序更方便的移植到C++中来,建议养成强制转换的习惯。
第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。
在Linux中可以有这样:malloc(0),这是因为Linux中malloc有一个下限值16Bytes,注意malloc(-1)是禁止的;但是在某些系统中是不允许malloc(0)的。
在规范的程序中我们有必要按照这样的格式去使用malloc及free:
type *p;
if(NULL == (p = (type*)malloc(sizeof(type))))
/*请使用if来判断,这是有必要的*/
{
perror("error...");
exit(1);
}
.../*其它代码*/
free(p);
p = NULL;/*请加上这句*/
malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。
比如想分配100个int类型的空间:
int *p = (int*)malloc(sizeof(int) * 100);
//分配可以放得下100个整数的内存空间。
另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。
对其做一个特例补充
char *ptr;
if((ptr = (char*)malloc(0)) == NULL)
puts("Gotanullpointer");
else
puts("Gotavalidpointer");
此时得到的是Got a valid pointer。把0赋给malloc能得到一个合法的指针。
上一篇: C语言 | 指针小结