问题描述
求协方差矩阵,但不知道如何把求得的结果传递出来。
数组怎么定义?在哪定义,定义成什么样?的问题
子函数内部定义静态的全局数组,数组大小不能准确确定,并且耗费空间大
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