欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++小结--指针

程序员文章站 2022-07-03 14:49:27
...

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能得到一个合法的指针。

相关标签: 指针