提问人:Pranav Vasishta 提问时间:3/6/2023 最后编辑:Pranav Vasishta 更新时间:3/7/2023 访问量:118
如果已经分配了内存,那么在函数内部的数组中所做的更改是否会保留在主函数或调用函数中?
If memory is already allocated, will changes made in the array inside a function be preserved in the main or calling functions?
问:
在这个函数定义中,我采用了 2D 数组地址的参数。
void dynamic(int ***a,int r,int c)
{
*a = (int**)malloc(sizeof(int*)*r);
for(int i=0;i<r;i++)
{
(*a)[i] = (int*)malloc(sizeof(int)*c);
}
}
我正在传递如下所示的参数,
dynamic(&a,r1,c1);
如果我直接将 2d 数组作为参数,那么它就不会接受输入。
但是,在这段代码中,在 add 函数中,我没有获取 2D 数组的地址,而是获取 2D 数组本身,但所做的更改被保留。
void add(int **a,int **b,int r,int c,int **sum)
{
static int i=0,j=0;
if(i>=r)
{
return;// sum;
}
else
{
if(j<c)
{
sum[i][j] = a[i][j]+b[i][j];
j++;
add(a,b,r,c,sum);
}
j=0;
i++;
add(a,b,r,c,sum);
}
}
但是,如果参考添加函数,我会得到垃圾值。
void add(int **a,int **b,int r,int c,int ***sum)
{
static int i=0,j=0;
if(i>=r)
{
return;
}
else
{
if(j<c)
{
(*sum)[i][j] = a[i][j]+b[i][j];
j++;
add(a,b,r,c,sum);
}
j=0;
i++;
add(a,b,r,c,sum);
}
}
#include<stdio.h>
#include<stdlib.h>
void input(int **a,int r,int c)
{
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
scanf("%d",&a[i][j]);
}
}
}
void dynamic(int ***a,int r,int c)
{
*a = (int**)malloc(sizeof(int*)*r);
for(int i=0;i<r;i++)
{
(*a)[i] = (int*)malloc(sizeof(int)*c);
}
}
int** matmul(int **a,int r1,int c1,int **b,int r2,int c2,int **c)
{
static int i=0,j=0,k=0;
if(i>r1)
{
return c;
}
else
{
if(j<c2)
{
if(k==0)
{
c[i][j]=0;
}
if(k<r2)
{
c[i][j]+= a[i][k]*a[k][j];
k++;
printf("product = %d ",c[i][j]);
matmul(a,r1,c1,b,r2,c2,c);
}
k=0;
j++;
matmul(a,r1,c1,b,r2,c2,c);
}
j=0;
i++;
matmul(a,r1,c1,b,r2,c2,c);
}
}
void freeing(int **arr,int r,int c)
{
for(int i=0;i<r;i++)
{
free(arr[i]);
}
free(arr);
}
void print_array(int **a,int r,int c)
{
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
return;
}
void main()
{
int **a,**b,r1,c1,r2,c2,i,j,**product;
printf("Enter the number of rows and columns in first matrix\n");
scanf("%d%d",&r1,&c1);
printf("Enter the number of rows and columns in first matrix\n");
scanf("%d%d",&r2,&c2);
if(r2==c1)
{
printf("Enter First array\n");
dynamic(&a,r1,c1);
input(a,r1,c1);
printf("Enter Second array\n");
dynamic(&b,r2,c2);
input(b,r2,c2);
printf("First matrix is\n");
print_array(a,r1,c1);
printf("Second matrix is\n");
print_array(b,r2,c2);
dynamic(&product,r1,c2);
{
if(product[0]==NULL)
{
printf("memory not allocated\n");
}
}
product=matmul(a,r1,c1,b,r2,c2,product);
printf("Product of 2 matrices are\n");
print_array(product,r1,c2);
freeing(a,r1,c1);
freeing(b,r2,c2);
freeing(product,r1,c2);
}
else
{
printf("Array multiplication not possible! enter correct dimension");
}
}
我试图编写用于动态分配 2D 数组的函数,但没有获取输入值,我将 2d ARRAY 的地址传递到动态函数中,这次它起作用了。我对添加函数应用了相同的逻辑,但我没有得到正确的结果,当我直接传递 2D 数组时,它起作用了,可能是什么原因。此外,我希望数组的维度由用户定义。
答:
此时:
(*sum)[i][j] = a[i][j]+b[i][j];
编译器不知道数组的维度,因为函数:
void add(int **a,int **b,int r,int c,int ***sum)
没有提供此类信息,换句话说,指向指针的指针和 2D 数组不是同一类型,您不能指望编译器从int(*)[dim]
int [][dim]
int **
从 C99 开始,您可以使用 VLA(可变长度阵列)来解决这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void add(int rows, int cols, int (*a)[cols], int (*b)[cols], int (*sum)[cols])
{
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
sum[row][col] = a[row][col] + b[row][col];
}
}
}
int main(void)
{
int rows = 2, cols = 3;
int ( *a )[cols] = malloc(sizeof(int) * rows * cols);
int ( *b )[cols] = malloc(sizeof(int) * rows * cols);
int (*sum)[cols] = malloc(sizeof(int) * rows * cols);
srand((unsigned)time(NULL));
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
a[row][col] = rand() % 100;
b[row][col] = rand() % 100;
}
}
add(rows, cols, a, b, sum);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
printf("%d + %d = %d, ", a[row][col], b[row][col], sum[row][col]);
}
printf("\n");
}
free(a);
free(b);
free(sum);
return 0;
}
请注意,VLA 在 C11 中是可选的
评论
scanf("%d", &rows); scanf("%d", &cols);
调用这两个递归函数的结果没有区别。
但是,这些函数有一个严重的缺点:如果多次调用它们,它们将不起作用,因为在调用函数后,静态变量的值不会重置为静态变量。i
0
声明参数也没有多大意义,例如sum
int **sum
因为该函数不会更改用作参数的指针本身。它更改指针指向的数据。
使用您的方法,可以按以下方式定义递归函数,如下面的演示程序所示。该函数被调用两次,以确保在第一次调用函数后,其静态变量被正确重置,并且可以第二次调用该函数。
在程序中,没有使用动态分配的数组来简化代码。
#include <stdio.h>
void add( int **a, int **b, unsigned int r, unsigned int c, int **sum )
{
static unsigned int i = 0, j = 0;
if (i < r && j != c)
{
sum[i][j] = a[i][j] + b[i][j];
if (++j == c)
{
j = 0;
++i;
}
add( a, b, r, c, sum );
}
else
{
i = 0;
}
}
int main( void )
{
enum { r = 2, c = 3 };
int a0[c] = { 1, 2, 3 };
int a1[c] = { 4, 5, 6 };
int * aa[r] = { a0, a1 };
int ** a = aa;
int b0[c] = { 10, 20, 30 };
int b1[c] = { 40, 50, 60 };
int * bb[r] = { b0, b1 };
int ** b = bb;
int s0[c];
int s1[c];
int * ss[r] = { s0, s1 };
int ** sum = ss;
add( a, b, r, c, sum );
for (unsigned int i = 0; i < r; i++)
{
for (unsigned int j = 0; j < c; j++)
{
printf( "%d ", sum[i][j] );
}
putchar( '\n' );
}
putchar( '\n' );
for (unsigned int j = 0; j < c; j++)
{
s0[j] = 0;
s1[j] = 0;
}
add( a, b, r, c, sum );
for (unsigned int i = 0; i < r; i++)
{
for (unsigned int j = 0; j < c; j++)
{
printf( "%d ", sum[i][j] );
}
putchar( '\n' );
}
}
程序输出为
11 22 33
44 55 66
11 22 33
44 55 66
可以看出,该函数每次被调用时都能正常工作。
函数的参数 和 具有无符号整数类型,而不是因为将它们声明为具有有符号整数类型是没有意义的。虽然一般来说,最好不要使用类型,而是使用类型。r
c
unsigned int
int
unsigned int
size_t
评论
add
static
add
int a[5][10];
a
&a[0]
int (*)[10]