C++数组、指针、动态内存分配

二维数组作为函数的参数问题#includeiostreamusing namespace std;void print(int n,int a[][10]){//形参a是一个n行二维数组的首地址for(int i=0;in;i++){for(int j=0;j10;j++){couta[i][j] ;}coutendl;...

二维数组作为函数的参数问题

#include<iostream>
using namespace std;
void print(int n,int a[][10]){//形参a是一个n行二维数组的首地址
    for(int i=0;i<n;i++){
        for(int j=0;j<10;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
}
int main(){
    int k[3][10]={{0,1,2,3,4,5,6,7,8,9},
                {1,2,3,4,5,6,7,8,9,10},
                {2,3,4,5,6,7,8,9,10,11}};
    print(3,k);//传入二维数组的首地址
}
//另外函数定义时也可以这样定义 void print(int n,int *a[10]),代表a是一个指向二维数组的指针

和一维数组作为函数的参数一样,遵循的原则是形参的格式和实参的格式相同,形参是二维数组的首地址,则调用函数的时候传入函数的也是二维数组的首地址。

关于指针的一些细节

const int * point 和int * const point 的区别

const int * point 可以按照“断句”的方法来看  ( (const int) * point )指的是指向const int (int常量)的指针

int * const point 同样,“断句”为( (int * ) (const point ) )声明的是一个指向int型变量的const 指针,即常指针

综上,const貌似总是“修饰”紧跟其后的名称

空类型指针

一般的指针都会声明指针的类型,或是int型,或是char型,然而有一种特殊的void类型指针

void类型指针可以存储任意类型的数据地址,通过显示的转换,可以通过指针访问任意类型的数据

#include<iostream>
using namespace std;
int main(){
    void * p;
    int a=100;
    char b='A';
    string c="hello world";
    /*
    p是一个可以指向任何数据类型的指针,但是p不可以直接使用,因为这样非常不安全
    在C++中,指针必须要进行显式的转化成特定类型的指针才可以使用
    这里使用static_cast<typename * >来转换,然后访问特定的内容
    */
    p=&a;
    cout<<* static_cast<int * >(p)<<endl;
    p=&b;
    cout<<* static_cast<char * >(p)<<endl;
    p=&c;
    cout<<* static_cast<string * >(p)<<endl;
}

空指针

空指针(区别于空类型指针)可以通过0或者NULL来初始化,NULL在很多头文件中都会有宏定义,定义成0

指针数组和二维数组

#include<iostream>
using namespace std;
int main(){
    //指针数组存储的是地址,而存储地址的变量和所有的变量一样,需要开辟内存空间
    int line1[]={0,1,2,3,4,5,6,7,8,9};
    int line2[]={9,8,7,6,5,4,3,2,1,0};
    int line3[]={1,3,5,7,9,0,8,6,4,2};
    int *point[3]={line1,line2,line3};
    //(int * ) point [3] 
    for(int i=0;i<3;i++){
        for(int j=0;j<10;j++){
            cout<<point[i][j]<<" ";
        }
        cout<<endl;
    }
}

point [ i ] [ j ]的语法格式和二维数组访问的格式完全相同,但是二者实质上有着明显的差异

#include<iostream>
using namespace std;
int main(){
    int a[3][10]={{0,1,2,3,4,5,6,7,8,9},{9,8,7,6,5,4,3,2,1,0},{1,3,5,7,9,0,8,6,4,2}};
    for(int i=0;i<3;i++){
        for(int j=0;j<10;j++){
            cout<<a[i][j]<<" ";
        }
        cout<<endl;
    }
}

两种语法都使用了二维数组的访问方式,但是实质上访问的过程完全不同

 

 指向函数的指针

声明指向函数的指针语法

数据类型 ( * 函数指针名)(形参表)

有时候多次定义同一个类型的指向函数的指针会很繁琐,这个时候可以使用typedef来定义

typedef int (* function)(double);
function a;//function此时成为了一个类型名
function b;
………………

int (* function)(double)
………………
int a(double b){
     ……  
}
funtion=a;
double c=9.001;
function(c);//这个时候,function是具体的指向函数的指针

动态内存分配

动态内存分配的初始化

1.不初始化 int *point = new int ;

2.0初始化 int * point = new int ( );

3. 指定初始化 int * point =new int (1);

对于对象,0初始化和不初始化的效果是一样的,都是使用默认的构造函数。也许可以把0初始化看作是系统指定变量对应的构造函数?

动态分配数组

在释放用new建立的数组的时候,需要使用 delete [ ]指针名来释放数组空间

 

本文标题为:C++数组、指针、动态内存分配

基础教程推荐