数组可以看做为一种类型,与指针不同,但是可以相互转化。
一 C指针操作函数
new和delete对C++的程序员也许很熟悉,但是malloc和free被用来在C代码中用来内存分配和释放,很多C++开发者并不能游刃有余的使用,下面实例解析malloc和free的使用。
实例如下:
Code
#pragmaonce
#include<string>
voidTestMallocAndFree()
{
char*ptr=NULL;
ptr=(char*)malloc(100*sizeof(char));
if(NULL==ptr)
{
return;
}
memcpy(ptr,"Hello!",strlen("Hello!"));
free(ptr);
ptr=NULL;
typedefstructdata_type
{
intage;
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
#pragmaonce
#include<iostream>
usingnamespacestd;
voidPrintArray(double*p,intnum)
{
for(inti=0;i<num;++i)
{
cout<<""<<p[i]<<"";
}
cout<<endl<<"Thearrayisend!"<<endl;
}
voidPrintArray(doublearr[3])
{
for(inti=0;i<3;++i)
{
cout<<""<<*(arr+i)/*arr[i]*/<<"";
}
cout<<endl<<"Thearrayisend!"<<endl;
}
voidChangeArray(doublearr[3])//数组传参为传指针,所以函数内可以修改
{
for(inti=0;i<3;++i)
{
arr[i]=10;
}
}
voidPrintArray(doublearr[3][3])
{
for(inti=0;i<3;++i)
for(intj=0;j<3;++j)
cout<<""<<arr[i][j]<<"";
cout<<endl<<"Thearrayisend!"<<endl;
}
intGetLength(){return3;}
voidTestArray()
{
//数组的定义和初始化
shortmonths[12]={31,28,31,30,31,30,31,31,30,31,30,31};
doublearr[3];
arr[0]=1.0;
arr[1]=2.0;
arr[2]=3.0;
doublearr2[]={1.0,2.0,3.0};
//doublearr3[3]=arr;//error
PrintArray(arr,3);
PrintArray(&arr[0],3);
PrintArray(arr2);
doublematrix2[2][2]={1.0,0.0,0.0,1.0};
doublematrix3[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=newdouble[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]=newdouble[2];
p4[1]=newdouble[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) 当函数传入数组,实际传首元素的指针,所以可以在函数内修改数组元素。
三 完!