C++二维数组传递参数哪些事儿

问题描述

求协方差矩阵,但不知道如何把求得的结果传递出来。

数组怎么定义?在哪定义,定义成什么样?的问题

子函数内部定义静态的全局数组,数组大小不能准确确定,并且耗费空间大
function1
function2
function3
里的返回字符串使用静态就好,比如:
char * function1 ( char * s )
{
static char ret[100];
……
return ret;
}
在主函数中怎么能事先分配刚好返回结果那么大的空间?
如果一个C++函数是:
string F(const string&)
那么对应C函数应该像这样:
int F(char * dst, const char * src)
内存分配不由函数负责,而是外部传入预先分配好的内存的指针在函数里使用

typedef struct {
int len;
char *s;
} dynString;
/// 用这样一个结构模拟 string 就可以了
/// 例如 合并字符串
dynString mergeStr( dynString *a,dynString *b)
{
dybString ds;

if(a==NULL||b==NULL){
ds->len =0;
ds->s=NULL;
return ds;
}

ds.len= a->len+b->len;
ds.s =malloc(ds.len+1);
strcpy(ds->s,a->s);
strcat(ds->s,b->s);
return ds;
}
看了这里大致明白了指针的使用和函数的定义,要想返回指针必须定义函数类型为指针,而指针是变量内存空间的地址。

动态开辟二维数组(?)

C++ new 法

#include <iostream>
#include <iomanip>

using namespace std;

void main()
{
    int row, col;
    int **element = NULL; 

    cin>>row
        >>col;

    //动态开辟数组
    element = new int *[row];

    for (int i = 0; i < row; i++)
    {
        element[i] = new int[col];
    } 

    //输入数组
    cout<<endl;

    for (i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            cin>>element[i][j];
        }
    }

    //输出数组
    cout<<endl;

    for (i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            cout<<setw(5)<<element[i][j];
        }
        cout<<endl;
    }
}

销毁开辟的空间

//销毁空间
    for (i = 0; i < row; i++)
    {
        delete []element[i];
        element[i] = NULL;
    }
    delete []element;
    element = NULL;

这是销毁开辟的空间的代码!

用new在堆上开辟的空间,必须要用delete释放了,不然要出现内存泄露了!

从这里感觉重点是二级指针的问题,虽然能运行通过,但二维数组真的对应二级指针吗?答案在下面

二维数组用指针引用

在C/c++中没有所谓的二维数组,书面表达就是数组的数组。
一、二维数组一维化
首先,定义一个二维数组。

int iArr[2][3]={0,1,2,3,4,5};

我们可以用一个指向int型的指针变量来访问这个数组,下面的代码是将数组一维化:

int* p = iArr[0];
上面的iArr[0]就是代表第一个数组的首地址,由于二维数组在内存中的存储也是先行后列的方式,所以第二行也紧跟第一行之后,这样就可以用p来访问数组的元素值了,访问的方式有下标和指针方式。

printf(“%d,”,p[3]);
printf(“%d\n”,*(p+3));
最后输出的结果都是3。讲完了一维化之后,下面来继续看二维数组的函数名到底是什么意思?

二、关于二维数组名的探索
可能想当然的话,二维数组不就是一个二级指针吗?真是这样吗?下面用代码来验证下:

int **pp = iArr;
不出意外,会出现下面的编译错误:
error C2440: “初始化”: 无法从“int [2][3]”转换为“int **”
其实二维数组名是一个数组指针,那什么是数组指针?数组指针是指向一个数组首地址的指针,它实际上也是一种指针类型,类似于函数指针。它声明如下:

int (*pArr)[3]
它说明pArr是一个数组指针,它指向的是一个数组元素为int类型并且数组元素的个数为3的一个数组指针,奇怪,中间的怎么还有一个括号是啥玩意?呵呵,这个括号还真是不可少的。少了它就变为另外一种类型了:指针数组。指针数组是数组类型,代表数组的每一个元素是指针类型,它声明如下:int *pArr[3]。
既然二维数组的数组名是指向第一行数组的首地址,我们也叫它行指针。那么我们可以用这种数组名或者指针来访问二维数组的元素。

int (*pArr)[3] = iArr;
下面,我要访问第一行第二列的元素,我可以用下面的代码来访问

*(*(pArr+1) + 2)  

也可以用数组名来访问:

*(*(iArr+1) + 2)  

这种方式是不是一下很难看懂,为什么两个星号啊?仅以pArr做说明
首先,pArr是一个指向数组的指针,在这个指针上加减一个整数都是移动整行,而不是一个元素。比如说,pArr+1代表的现在指针已经指向第一行元素了,也就是实际中的第二行,而要取得指针所指的对象,就要用到解引用运算符*,所以*(pArr+1)就代表第一行数组,是整个这一行元素就取到了,那现在要取这一行的第二个元素,只须将指针再移动两个元素,即*(iArr+1) + 2,这样就指向了这个元素的地址,再解引用取得元素的值即可。

三、作为函数参数
一维数组名作为函数参数实际上是退化为指针,二维数组作为函数参数又有什么不同呢?下面举个例子说明。
声明了如下函数:
void TestFun(int *pArr,int nlength)
假设,我用数组名和指向首个元素地址的指针作为传递参数,看看有什么效果?

TestFun(iArr,6);//“TestFun”: 不能将参数 1 从“int [2][3]”转换为“int *”  
TestFun(&iArr[0][0],6);  

直接传递数组名是编译通不过的。因为数组名是数组指针,而函数的参数是int*,两者的类型化完全不一样,所以不能转换。
而数组首元素的地址显然是int*类型,所以就能编译通过。

假设,我现在把这个函数的声明换一下,看看这两种传参的方法会出现什么情况?
现在的声明是:

void TestFun(void *pArr,int nlength)
还是这样传参,

TestFun(iArr,6);  
TestFun(&iArr[0][0],6);  

编译一下,居然都能通过了。在这里,第二种方式显然是没问题的,因为int*可以转化为void*。而第一种方式怎么就可以了呢?因为iArr是数组指针,当然也可以转换为void*啦。

二级指针和一级指针的区别

最后的最后,突然发现,并不需要传递,问题的方向搞反了,重要的是把全局变量传递进去,改变变量值,不需要传递出来……

问题的分析永远是最重要的!

thanks:
http://blog.csdn.net/zhouxuguang236/article/details/12256321
http://blog.csdn.net/vipygd/article/details/5909817

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z_shsf

来包瓜子嘛,谢谢客官~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值