[C++对象模型][3]指针与数组

本文探讨了C++中的指针与数组的关系,包括C指针操作函数malloc和free的使用,以及new和delete的区别。文章还强调了数组与指针的交互,如动态分配数组、内存管理以及二维数组的特性。最后提到了数组作为函数参数时的行为。
摘要由CSDN通过智能技术生成

 

数组可以看做为一种类型,与指针不同,但是可以相互转化。

 

一 C指针操作函数

new和delete对C++的程序员也许很熟悉,但是malloc和free被用来在C代码中用来内存分配和释放,很多C++开发者并不能游刃有余的使用,下面实例解析malloc和free的使用。

       mallocvoid *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。
       freevoid free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。

 

实例如下:

 

Code
#pragma once
#include 
<string>

void TestMallocAndFree()
{
    
char *ptr = NULL;
    ptr 
= (char*)malloc(100 * sizeof(char));
    
if (NULL == ptr)
    {
        
return;
    }
    memcpy(ptr,
"Hello!",strlen("Hello!"));
    free(ptr);
    ptr 
= NULL;

     typedef 
struct data_type 
     {
       
int age;
       
char *name;
     } data;
 
     data 
*willy = NULL;
     willy 
= (data*) malloc( sizeof(data) );
     willy
->age = 20;
     willy
->name = "jason"// 此时的name指向了常量区,所以name指针不需要程序员释放。
     free( willy );
     willy 
= NULL;
}

 

malloc/free 和new/delete的区别:

1)new/delete是保留字,不需要头文件支持. malloc/free需要头文件库函数支持. 使用malloc/free需要包含 #include<cstdlib> 或<stdlib>.

2) new 建立的是一个对象,new会根据对象计算大小,直接返回对象的指针,当使用完毕后调用delete来释放,但malloc分配的是一块内存,需要用户制定所要分配内存的大小,而且返回的均为void的指针,使用时需要相应的强制类型转化,使用结束后调用free来释放内存.

3)new/delete的使用除了分配内存和释放,还调用了类型的构造函数和析构函数,而malloc/free只是简单的分配和释放内存。

二 数组与指针

C++的数组经常需要和指针来结合使用,下面来进行相关的强化训练。实例如下:

 

Code
#pragma once
#include 
<iostream>
using namespace std;

void PrintArray(double *p, int num)
{
    
for(int i = 0; i < num; ++i)
    {
        cout 
<< " " << p[i] << " ";
    }
    cout 
<< endl << "The array is end!" << endl;
}
void PrintArray(double arr[3]) 
{
    
for(int i = 0; i < 3++i)
    {
        cout 
<< " " << *(arr+i)/*arr[i]*/ << " ";
    }
    cout 
<< endl << "The array is end!" << endl;
}
void ChangeArray(double arr[3]) // 数组传参为传指针,所以函数内可以修改
{
    
for(int i = 0; i < 3++i)
    {
        arr[i] 
= 10;
    }
}
void PrintArray(double arr[3][3])
{
    
for(int i = 0; i < 3++i)
        
for(int j = 0; j < 3++j)
            cout 
<< " " << arr[i][j] << " ";
    cout 
<< endl << "The array is end!" << endl;
}

int GetLength(){return 3;}

void TestArray()
{
    
// 数组的定义和初始化
    short months[12= {31,28,31,30,31,30,31,31,30,31,30,31};
    
double arr[3]; 
    arr[
0= 1.0;
    arr[
1= 2.0;
    arr[
2= 3.0;
    
double arr2[] = {1.0,2.0,3.0};
    
//double arr3[3] = arr; // error
    PrintArray(arr,3);
    PrintArray(
&arr[0],3);
    PrintArray(arr2);

    
double matrix2 [2][2= {1.0,0.0,0.0,1.0};
    
double matrix3 [3][3= {{1.0,0.0,0.0},
                            {
0.0,1.0,0.0},
                            {
0.0,0.0,1.0}};
    PrintArray(matrix3[
0],3*3);
    PrintArray(
&matrix3[0][0],3*3);
    
//PrintArray(matrix3,3*3);
    PrintArray(matrix3);

    
// 指针来模拟数组
    double *p3 = new double[GetLength()];
    p3[
0= 10.0;
    p3[
1= 20.0;
    p3[
2= 30.0;
    PrintArray(p3,
3);
    PrintArray(p3);
    delete []p3;

    
// 数组+指针实现二维变长数组
    double *p4[2];
    p4[
0= new double[2];
    p4[
1= new double[4];
    p4[
0][0= 10;
    p4[
0][1= 20;
    p4[
1][0= 30;
    p4[
1][1= 40;
    p4[
1][2= 50;
    p4[
1][3= 60;
    PrintArray(p4[
0],2);
    PrintArray(p4[
1],4);
    delete [] p4[
0];
    delete [] p4[
1];

    PrintArray(arr); 
// 数组传参为传指针,所以函数内可以修改
    ChangeArray(arr);
    PrintArray(arr);
}

 

代码分析总结:

1)数组的定义必须使用常量指定长度,例如:double arr[3],但是使用指针时可以是运行时指定,例如double *p3 = new double[getLength()]。
2)数组定义时即分配空间且在栈上,不需要程序员来对内存管理,但是如果对指针使用了new[],则必须由程序员在使用完毕后delete[]。
3) 一维数组数组名即第一个元素的地址,例如:double arr[3]中,arr == &arr[0]为true。
4)二维数组中第一行的地址即为第一个元素的地址,例如:double matrix3 [3][3],matrix[0] == &matrix[0][0]为true。
5)可以使用指针数组来模拟变长二维数组,例如:double *p4[2]; p4[0] = new double[2]; p4[1] = new double[4];
6)二维数组内存中同一维数组仍为连续的区域,所以可以将二维数组和一维相互转化。
7)一维数组名即为第一个元素的地址,所以可以同指针隐式转化,但二维数组名不是第一个元素地址,所以不能转化。
8) 当函数传入数组,实际传首元素的指针,所以可以在函数内修改数组元素。

三 完!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值