我正在练习使用malloc
功能。我已经声明了两个复杂的矩阵:H
和result
。 H
的所有元素都是1.1 + 0i,result
的所有元素都是0 + 2.2i作为原始值。我已将H
复制到result
,然后将其打印出来。结果显示一些元素只是0 + 0i,显然不是这种情况。你能帮我弄清楚代码中出了什么问题吗?
/*
* This C code is for simulation for printing complex channel matrix by using struct
*
* let matrix H be 8 by 4
* 2017.05.24
*
*/
#include "math.h"
#include "complex.h"
#include <stdio.h>
#include <stdlib.h>
struct str_dcomplex
{
double re;
double im;
};
typedef struct str_dcomplex dcomplex;
int main() {
void print_matrix(char* desc, int m, int n, dcomplex a[m][n]) {
int i, j;
printf("\n%s\n",desc);
for(i = 0; i < m; i++) {
for(j = 0; j < n; j++) {
printf("(%5.1f,%5.1f)",a[i][j].re, a[i][j].im);
}
printf("\n");
}
}
void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c]) {
int i, j;
for(i = 0; i < r; i++) {
for(j = 0; j < c; j++) {
dest[i][j].re = source[i][j].re;
dest[i][j].im = source[i][j].im;
}
}
}
int p,q;
int i,j;
// memory allocation for H
dcomplex **H;
H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}
// dcomplex(*H)[4] = dcomplex(*)[4]malloc(sizeof(dcomplex)*8*4);
for(p = 0; p < 8; p++) {
for(q = 0; q < 4; q++) {
H[p][q].re = 1.1;
H[p][q].im = 0.0;
}
}
dcomplex** result;
result = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
result[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}
for(p = 0; p < 8; p++) {
for(q = 0; q < 4; q++) {
result[p][q].re = 0.0;
result[p][q].im = 2.2;
}
}
// declare and assign variables
//dcomplex H[8][4] = {{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}},{{1,2},{3,4},{5,6},{7,8}}};
//dcomplex result[8][4] = {{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}},{{0,0},{0,0},{0,0},{0,0}}};
// print H and result
print_matrix("original H is: \n",8,4,H);
print_matrix("original result is: \n",8,4,result);
// copy H to result
matrix_copy(8,4,H,result);
// print H and result
print_matrix("new H is: \n",8,4,H);
print_matrix("new result is: \n",8,4,result);
int count = 0;
for(i = 0; i < 8; i++) {
for(j = 0; j < 4; j++){
if((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
count++;
}
}
printf("\n%d\n\n",count);
//printf("\nmatrix copy completed...\n\n");
//printf("\nSize of dcomplex is: %d\n\n",sizeof(dcomplex));
// free the memory
for(i = 0; i < 8; i++) {
free(H[i]);
}
free(H);
for(i = 0; i < 8; i++) {
free(result[i]);
}
free(result);
return 0;
}
执行结果的屏幕截图:
更新:我将print_matrix
和matrix_copy
,dcomplex a[m][n]
的参数更改为dcomplex** a[m][n]
,dcomplex source[r][c]
更改为{{1 }}和dcomplex** source[r][c]
...和dest
到a[i][j].re
等等。它仍然不起作用......无法弄清楚错误。
答案 0 :(得分:1)
你正在使用malloc。
dcomplex **H;
H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}
我认为这些是有问题的行?您将不得不调试其余代码来解决问题。
答案 1 :(得分:1)
您没有使用<math.h>
或<complex.h>
中的任何内容 - 您使用自己的dcomplex
类型。那些标题也可能不存在。
嵌套函数符号是令人厌恶的 - GCC允许它,但它不应该,并且你不应该使用符号。
当函数被取消时(我拒绝找出它们嵌套时会发生什么),编译器会痛苦而公正地抱怨:
cx19.c: In function ‘main’:
cx19.c:76:42: error: passing argument 4 of ‘print_matrix’ from incompatible pointer type [-Werror=incompatible-pointer-types]
print_matrix("original H is: \n",8,4,H);
^
cx19.c:15:6: note: expected ‘dcomplex (*)[(sizetype)(n)]’ but argument is of type ‘dcomplex ** {aka struct str_dcomplex **}’
void print_matrix(char* desc, int m, int n, dcomplex a[m][n]) {
^~~~~~~~~~~~
cx19.c:77:47: error: passing argument 4 of ‘print_matrix’ from incompatible pointer type [-Werror=incompatible-pointer-types]
print_matrix("original result is: \n",8,4,result);
^~~~~~
您传递dcomplex **
并假装它是dcomplex[m][n]
类型。我很遗憾地通知您编译器是正确的并且您的代码是错误的。
如果要传递可变长度的2D数组,则必须分配可变长度的2D数组。如果要将指针传递给指针,则必须修改函数。
更改功能很容易;只需更改相关参数的类型即可。请注意,除了函数签名的更改之外,函数没有其他必要的更改。
#include <stdio.h>
#include <stdlib.h>
struct str_dcomplex
{
double re;
double im;
};
typedef struct str_dcomplex dcomplex;
static
void print_matrix(char* desc, int m, int n, dcomplex **a) {
int i, j;
printf("\n%s\n",desc);
for(i = 0; i < m; i++) {
for(j = 0; j < n; j++) {
printf("(%5.1f,%5.1f)",a[i][j].re, a[i][j].im);
}
putchar('\n');
}
}
static
void matrix_copy(int r, int c, dcomplex **source, dcomplex **dest) {
int i, j;
for(i = 0; i < r; i++) {
for(j = 0; j < c; j++) {
dest[i][j].re = source[i][j].re;
dest[i][j].im = source[i][j].im;
}
}
}
int main(void) {
int p,q;
int i,j;
// memory allocation for H
dcomplex **H;
H = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
H[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}
for(p = 0; p < 8; p++) {
for(q = 0; q < 4; q++) {
H[p][q].re = 1.1;
H[p][q].im = 0.0;
}
}
dcomplex** result;
result = (dcomplex**)malloc(sizeof(dcomplex*)*8);
for(p = 0; p < 8; p++) {
result[p] = (dcomplex*)malloc(sizeof(dcomplex)*4);
}
for(p = 0; p < 8; p++) {
for(q = 0; q < 4; q++) {
result[p][q].re = 0.0;
result[p][q].im = 2.2;
}
}
// print H and result
print_matrix("original H is: \n",8,4,H);
print_matrix("original result is: \n",8,4,result);
// copy H to result
matrix_copy(8,4,H,result);
// print H and result
print_matrix("new H is: \n",8,4,H);
print_matrix("new result is: \n",8,4,result);
int count = 0;
for(i = 0; i < 8; i++) {
for(j = 0; j < 4; j++){
if((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
count++;
}
}
printf("\n%d\n\n",count);
// free the memory
for(i = 0; i < 8; i++) {
free(H[i]);
}
free(H);
for(i = 0; i < 8; i++) {
free(result[i]);
}
free(result);
return 0;
}
该输出是:
original H is:
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
original result is:
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)( 0.0, 2.2)
new H is:
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
new result is:
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)( 1.1, 0.0)
32
动态分配可变长度数组并将它们传递给函数也是完全可行的。这导致代码如下:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct str_dcomplex
{
double re;
double im;
};
typedef struct str_dcomplex dcomplex;
static void print_matrix(char *desc, int m, int n, dcomplex a[m][n])
{
int i, j;
printf("\n%s\n", desc);
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
printf("(%5.1f,%5.1f)", a[i][j].re, a[i][j].im);
putchar('\n');
}
}
static void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
{
int i, j;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
dest[i][j] = source[i][j];
}
}
int main(void)
{
int p, q;
int i, j;
// memory allocation for H
dcomplex(*H)[4] = malloc(sizeof(H[0]) * 8);
assert(H != 0); // Sloppy!
for (p = 0; p < 8; p++)
{
for (q = 0; q < 4; q++)
H[p][q] = (dcomplex){ .re = 1.1, .im = 0.0 };
}
dcomplex (*result)[4] = malloc(sizeof(result[0]) * 8);
assert(result != 0); // Sloppy!
for (p = 0; p < 8; p++)
{
for (q = 0; q < 4; q++)
result[p][q] = (dcomplex){ .re = 0.0, .im = 2.2 };
}
// print H and result
print_matrix("original H is:", 8, 4, H);
print_matrix("original result is:", 8, 4, result);
// copy H to result
matrix_copy(8, 4, H, result);
// print H and result
print_matrix("new H is:", 8, 4, H);
print_matrix("new result is:", 8, 4, result);
int count = 0;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 4; j++)
{
if ((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
count++;
}
}
printf("\n%d\n\n", count);
// free the memory
free(H);
free(result);
return 0;
}
代码还使用了一些带有指定初始值设定项的复合文字,并且松散错误检查内存分配。使用assert()
进行错误检查在生产代码中是不明智的;这不是生产代码,它就足够了。
输出非常相似 - 矩阵描述和矩阵数据之间没有空行。
#include <stdio.h>
struct str_dcomplex
{
double re;
double im;
};
typedef struct str_dcomplex dcomplex;
static void print_matrix(char *desc, int m, int n, dcomplex a[m][n])
{
printf("\n%s\n", desc);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("(%5.1f,%5.1f)", a[i][j].re, a[i][j].im);
putchar('\n');
}
}
static void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
dest[i][j] = source[i][j];
}
}
static void matrix_init(int r, int c, dcomplex target[r][c], dcomplex value)
{
for (int p = 0; p < r; p++)
{
for (int q = 0; q < c; q++)
target[p][q] = value;
}
}
int main(void)
{
int r = 8;
int c = 4;
dcomplex H[r][c];
matrix_init(r, c, H, (dcomplex){ .re = 1.1, .im = 0.0 });
dcomplex result[r][c];
matrix_init(r, c, result, (dcomplex){ .re = 0.0, .im = 2.2 });
// print H and result
print_matrix("original H is:", r, c, H);
print_matrix("original result is:", r, c, result);
// copy H to result
matrix_copy(r, c, H, result);
// print H and result
print_matrix("new H is:", r, c, H);
print_matrix("new result is:", r, c, result);
int count = 0;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if ((H[i][j].re == result[i][j].re) && (H[i][j].im == result[i][j].im))
count++;
}
}
printf("\n%d\n\n", count);
return 0;
}
使用可变长度数组的更改很简单,这意味着我们不再需要使用<stdlib.h>
。我创建了matrix_init()
函数来初始化数组 - 它减少了main()
函数中的重复。如果使用在运行时确定的数组大小,则必须对数组大小进行完整性检查;堆栈上有多少可用空间是有限制的。但是,这些数组的大小(8 * 4 * 2 * sizeof(double)
,通常为512字节)不会给任何现代桌面计算机带来压力。
使用经典固定大小数组的改变是微不足道的。设置r
和c
值的更改同样基本上是微不足道的。
答案 2 :(得分:-2)
我不确定这是不是问题,而是将dcomplex dest
传递给了
void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
仅传递该值。您应该将matrix_copy(8,4,H,result)
更改为matrix_copy(8,4,H, &result)
和
void matrix_copy(int r, int c, dcomplex source[r][c], dcomplex dest[r][c])
来
void matrix_copy(int r, int c, dcomplex **source, dcomplex ***dest)