传递二维数组作为函数参数

时间:2022-08-25 21:28:47
形参mx的具体写法是什么样的?
我知道可以用(*mx)[5]表示,可我想把数组的数据和维数分开,维数分别用m,n表示,这样可以传递不同大小的数组而不用修改函数

double* ff( double  ##mx##,  double* vr, int m, int n)
{  double* tmv = new double [m];
   for (int i= 0; i < m; i++) 
   {
      tmv[i] = 0;
      for (int j=0; j<n; j++) tmv[i] += mx[i][j]*vr[j];
   }
   return tmv;
}

int main()
{
...
   double aa[][5] = { 0.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 5.0, 6.0, 7.0, 8.0 };   
   double bb[5] = {5, 8, 11, 14, 17};

   double* c = ff( aa ,bb,m,n);
...
}

10 个解决方案

#1


形参mx的具体写法是什么样的?
我知道可以用(*mx)[5]表示,可我想把数组的数据和维数分开,维数分别用m,n表示,这样可以传递不同大小的数组而不用修改函数

double* ff( double  ##mx##,  double* vr, int m, int n)
{  double* tmv = new double [m];
   for (int i= 0; i  < m; i++) 
   {
      tmv[i] = 0;
      for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j];
   }
   return tmv;


可以使用二维指针:
double* ff( double  **mx,  double* vr, int m, int n)
{  double* tmv = new double [m];
   for (int i= 0; i  < m; i++) 
   {
      tmv[i] = 0;
      for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j];
   }
   return tmv;

#2


double* ff( double  *mx[],  double* vr, int m, int n) 

double* ff( double  **mx,  double* vr, int m, int n) 

另外提醒LZ new分配的内存用完后别忘了delete

#3


#include <stdio.h>
void func(int n, char  str[ ][5] )
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}

void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 func(3, str);
}

方法二,形参声明为指向数组的指针。

例如:

#include <stdio.h>
void func(int n, char  (*str)[5] )
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}

void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 func(3, str);
}

 方法三,形参声明为指针的指针。

例如:

#include <stdio.h>
void func(int n, char **str)
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}
void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 p[0] = &str[0][0];
 p[1] = str[1];
 p[2] = str[2];
    func(3, p);
}


不好意思, 处理方法不是很简便, 直接贴别人的代码, 也许对你有些帮助.

#4


另一个变通的解决办法:
向函数传递数组:  
  1。数组名作函数参数,传递的是二维数组的首地址。  
  2。数组元素作函数参数,传递的是数组元素的值。  
   
  由于二维数组在内存中是线性排列的,传递一维数组和传递二维数组都是传的地址,所以在被调用的函数中用单循环来遍历二维数组中的所有元素,此时只要传递数组名和元素总个数。要注意被传递的数组地址不要用数组名表示,要用第一个元素的地址表示,因为数组名表示的是二维数组的首地址,尽管地址相同,但操作不同。

#include <iostream>

void func(int *array, int length) {
    for (int i = 0; i < length; ++i) {
        array[i] = i;
    }
}

int main() {
    const int length1 = 5;
    const int length2 = 5;
    int array[length1][length2];

    func(array[0], length1 * length2);

    for (int i = 0; i < length1; ++i) {
        for (int j = 0; j < length2; ++j) {
            std::cout << array[i][j] << "\t";
        }
        std::cout << std::endl;
    }

    return 0;
}

#5


double* ff( double  (*mx)[5],  double* vr, int m, int n) 
或double* ff( double  mx[][5],  double* vr, int m, int n) 可以实现

但是double* ff( double  **mx,  double* vr, int m, int n)不行,出错的提示是:
cannot convert parameter 1 from 'double [3][5]' to 'double **' 




#6


int mxvrmy( double  *mx1,  double* vr, const int m, const int n, double *c )

   double **mx2 = new double *[m];
   for(size_t i=0; i !=m; ++i) 
   mx2[i] = new double [n];

   for (size_t i= 0; i < m; ++i) 
    {
       for (size_t j=0; j<n; ++j) 
          mx2[i][j] = *(mx1++);
       }

   for (size_t i= 0; i < m; ++i) 
   {
      for (size_t j=0; j<n; ++j) 
 c[i] += mx2[i][j]*vr[j];
      }

   for (size_t i =0; i != m; ++i)
delete [] mx2[i];
   delete  [] mx2;

   return 1;
}



int main()
{...
   const int m=3;
   const int n=5;  
   double aa[m][n] = { 0.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 5.0, 6.0, 7.0, 8.0 };   
   double bb[n] = {5, 8, 11, 14, 17};   
   double *pp = (double *)aa;
   double cc[m]={0};   
   mxvrmy( pp ,bb,m,n, cc);
...
}

#7



//根据楼主的程序改写的向一个函数传入不同的二维数组.
double* ff( double **mx, /* double* vr,*/ int m, int n) 
{  
/* double* vr,
double* tmv = new double [m]; 
for (int i= 0; i  < m; i++)  

tmv[i] = 0; 
for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j]; 
} */
    
    //
    for(int i=0;i<m;i++)
    {
        for(int k=0;k<n;k++)
        {
            std::cout<<mx[i][k]<<" ";//经过预处理过的双指针,可以象使用二维数组一样使用.
            //注意不要直接将二维数组强制转换为双指针传入,那样会出错的.
        }
        std::cout<<std::endl;
    }
    return 0; 


int main() 

    //... 
    double aa[][5] = { 0.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 5.0, 6.0, 7.0, 8.0 };    
    // double bb[5] = {5, 8, 11, 14, 17}; 
    //要把一个确定的二维数组用双指针传入函数内部.
    //需要做些处理.
    int m=sizeof(aa)/sizeof(aa[0]);
    int n=sizeof(aa[0])/sizeof(aa[0][0]);
    double** px=new double*[m];
    for(int i=0;i<m;i++)
    {
        px[i]=aa[i];
    }
    
    //可以用了.
    double* c = ff(px ,m,n); 
    //... 
    double aa2[][7] = { 10.0, 11.0, 12.0, 13.0, 14.0, 11.0, 12.0, 13.0, 14.0, 15.0, 14.0, 15.0, 16.0, 17.0, 18.0 ,15.0, 14.0, 15.0, 16.0, 17.0, 18.0 };    
    int m2=sizeof(aa2)/sizeof(aa2[0]);
    int n2=sizeof(aa2[0])/sizeof(aa2[0][0]);

    double** px2=new double*[m2];
    for(int k=0;k<m2;k++)
    {
        px2[k]=aa2[k];
    }
    ff(px2,m2,n2);

    delete []px;
    delete []px2;
    return 0;
}

#8


感谢黄瓜的指点!

但出了一点问题:
将main()中delete []px;改为
 

for(size_t i = 0; i != m; ++i)
    delete [] px[i];
    delete [] px;


出现如下的错误:
'example1.exe': Loaded 'F:\example1\debug\example1.exe', Symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcr80d.dll', Symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
HEAP[example1.exe]: Invalid Address specified to RtlValidateHeap( 003B0000, 0012FECC )
Windows has triggered a breakpoint in example1.exe.

This may be due to a corruption of the heap, and indicates a bug in example1.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information

#9


只new了px,你为什么要delete px[i]呢?

#10


呵呵,是我理解错了。非常感谢指点!
我把上面的代码和下面的弄混淆了。

int ** pt = new int *[100];
for (int i = 0; i != 100; ++i)
 pt[i] = new int [100];

#1


形参mx的具体写法是什么样的?
我知道可以用(*mx)[5]表示,可我想把数组的数据和维数分开,维数分别用m,n表示,这样可以传递不同大小的数组而不用修改函数

double* ff( double  ##mx##,  double* vr, int m, int n)
{  double* tmv = new double [m];
   for (int i= 0; i  < m; i++) 
   {
      tmv[i] = 0;
      for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j];
   }
   return tmv;


可以使用二维指针:
double* ff( double  **mx,  double* vr, int m, int n)
{  double* tmv = new double [m];
   for (int i= 0; i  < m; i++) 
   {
      tmv[i] = 0;
      for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j];
   }
   return tmv;

#2


double* ff( double  *mx[],  double* vr, int m, int n) 

double* ff( double  **mx,  double* vr, int m, int n) 

另外提醒LZ new分配的内存用完后别忘了delete

#3


#include <stdio.h>
void func(int n, char  str[ ][5] )
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}

void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 func(3, str);
}

方法二,形参声明为指向数组的指针。

例如:

#include <stdio.h>
void func(int n, char  (*str)[5] )
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}

void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 func(3, str);
}

 方法三,形参声明为指针的指针。

例如:

#include <stdio.h>
void func(int n, char **str)
{
 int i;
 for(i = 0; i < n; i++)
  printf("\nstr[%d] = %s\n", i, str[i]);
}
void main()
{
 char* p[3];
 char str[][5] = {"abc","def","ghi"};
 p[0] = &str[0][0];
 p[1] = str[1];
 p[2] = str[2];
    func(3, p);
}


不好意思, 处理方法不是很简便, 直接贴别人的代码, 也许对你有些帮助.

#4


另一个变通的解决办法:
向函数传递数组:  
  1。数组名作函数参数,传递的是二维数组的首地址。  
  2。数组元素作函数参数,传递的是数组元素的值。  
   
  由于二维数组在内存中是线性排列的,传递一维数组和传递二维数组都是传的地址,所以在被调用的函数中用单循环来遍历二维数组中的所有元素,此时只要传递数组名和元素总个数。要注意被传递的数组地址不要用数组名表示,要用第一个元素的地址表示,因为数组名表示的是二维数组的首地址,尽管地址相同,但操作不同。

#include <iostream>

void func(int *array, int length) {
    for (int i = 0; i < length; ++i) {
        array[i] = i;
    }
}

int main() {
    const int length1 = 5;
    const int length2 = 5;
    int array[length1][length2];

    func(array[0], length1 * length2);

    for (int i = 0; i < length1; ++i) {
        for (int j = 0; j < length2; ++j) {
            std::cout << array[i][j] << "\t";
        }
        std::cout << std::endl;
    }

    return 0;
}

#5


double* ff( double  (*mx)[5],  double* vr, int m, int n) 
或double* ff( double  mx[][5],  double* vr, int m, int n) 可以实现

但是double* ff( double  **mx,  double* vr, int m, int n)不行,出错的提示是:
cannot convert parameter 1 from 'double [3][5]' to 'double **' 




#6


int mxvrmy( double  *mx1,  double* vr, const int m, const int n, double *c )

   double **mx2 = new double *[m];
   for(size_t i=0; i !=m; ++i) 
   mx2[i] = new double [n];

   for (size_t i= 0; i < m; ++i) 
    {
       for (size_t j=0; j<n; ++j) 
          mx2[i][j] = *(mx1++);
       }

   for (size_t i= 0; i < m; ++i) 
   {
      for (size_t j=0; j<n; ++j) 
 c[i] += mx2[i][j]*vr[j];
      }

   for (size_t i =0; i != m; ++i)
delete [] mx2[i];
   delete  [] mx2;

   return 1;
}



int main()
{...
   const int m=3;
   const int n=5;  
   double aa[m][n] = { 0.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 5.0, 6.0, 7.0, 8.0 };   
   double bb[n] = {5, 8, 11, 14, 17};   
   double *pp = (double *)aa;
   double cc[m]={0};   
   mxvrmy( pp ,bb,m,n, cc);
...
}

#7



//根据楼主的程序改写的向一个函数传入不同的二维数组.
double* ff( double **mx, /* double* vr,*/ int m, int n) 
{  
/* double* vr,
double* tmv = new double [m]; 
for (int i= 0; i  < m; i++)  

tmv[i] = 0; 
for (int j=0; j <n; j++) tmv[i] += mx[i][j]*vr[j]; 
} */
    
    //
    for(int i=0;i<m;i++)
    {
        for(int k=0;k<n;k++)
        {
            std::cout<<mx[i][k]<<" ";//经过预处理过的双指针,可以象使用二维数组一样使用.
            //注意不要直接将二维数组强制转换为双指针传入,那样会出错的.
        }
        std::cout<<std::endl;
    }
    return 0; 


int main() 

    //... 
    double aa[][5] = { 0.0, 1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 5.0, 6.0, 7.0, 8.0 };    
    // double bb[5] = {5, 8, 11, 14, 17}; 
    //要把一个确定的二维数组用双指针传入函数内部.
    //需要做些处理.
    int m=sizeof(aa)/sizeof(aa[0]);
    int n=sizeof(aa[0])/sizeof(aa[0][0]);
    double** px=new double*[m];
    for(int i=0;i<m;i++)
    {
        px[i]=aa[i];
    }
    
    //可以用了.
    double* c = ff(px ,m,n); 
    //... 
    double aa2[][7] = { 10.0, 11.0, 12.0, 13.0, 14.0, 11.0, 12.0, 13.0, 14.0, 15.0, 14.0, 15.0, 16.0, 17.0, 18.0 ,15.0, 14.0, 15.0, 16.0, 17.0, 18.0 };    
    int m2=sizeof(aa2)/sizeof(aa2[0]);
    int n2=sizeof(aa2[0])/sizeof(aa2[0][0]);

    double** px2=new double*[m2];
    for(int k=0;k<m2;k++)
    {
        px2[k]=aa2[k];
    }
    ff(px2,m2,n2);

    delete []px;
    delete []px2;
    return 0;
}

#8


感谢黄瓜的指点!

但出了一点问题:
将main()中delete []px;改为
 

for(size_t i = 0; i != m; ++i)
    delete [] px[i];
    delete [] px;


出现如下的错误:
'example1.exe': Loaded 'F:\example1\debug\example1.exe', Symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f\msvcr80d.dll', Symbols loaded.
'example1.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
HEAP[example1.exe]: Invalid Address specified to RtlValidateHeap( 003B0000, 0012FECC )
Windows has triggered a breakpoint in example1.exe.

This may be due to a corruption of the heap, and indicates a bug in example1.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information

#9


只new了px,你为什么要delete px[i]呢?

#10


呵呵,是我理解错了。非常感谢指点!
我把上面的代码和下面的弄混淆了。

int ** pt = new int *[100];
for (int i = 0; i != 100; ++i)
 pt[i] = new int [100];