- 主题:请教两个二级指针的问题
我写了一段计算矩阵的转置矩阵的程序,运行虽然没有报错,但是我觉得我程序里是不是有两个错误?
(1)验证了if( AT == NULL )之后,没必要再验证if( AT[i] == NULL )吧?属于多此一举;
(2)定义**XT后缺少生成2行5列的全零矩阵的步骤。程序这次虽然没有出错,但容易出现内存地址被占用的情况?
有没有大牛给指点两句?谢谢
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
double ** Mat_tra(double **A,int Row_A,int Line_A)
//子函数:计算矩阵A的转置矩阵AT,
{
double **AT;//创建A的转置矩阵
int i,j;
AT=(double**)calloc(Line_A,sizeof(double*)); //
if( AT == NULL )
{
printf( "内存分配失败\n" );
return 0;
}
else
{};
for(i=0;i<Line_A;i++)
{
AT[i]=(double*)calloc(Row_A,sizeof(double));//
if( AT[i] == NULL )
{
printf( "内存分配失败\n" );
return 0;
}
else
{};
for(j=0;j<Row_A;j++)
{
AT[i][j]=A[j][i];
}
}
return AT;
}
void Print_mat(double **A,int Row_A,int Line_A)
//子函数:打印数组
{
int i,j;
for(i=0;i<Row_A;i++)//
{
for(j=0;j<Line_A;j++)
{
printf("%5.3g ",A[i][j]);
if(Line_A!=1)
//如果 Line_A==1,则会出现除以0的情况,子函数会不报错就退出;
{
if ((j!=0)&(j%(Line_A-1)==0) )
printf("\n");
}
else
{
printf("\n");
}
}
}
printf("\n");
}
int main()
{
double **X,**XT;
int i,j;
int Row_X=2;
int Line_X=5;
int Row_XT=5;
int Line_XT=2;
X=(double**)calloc(Row_X,sizeof(double*));
if( X == NULL )
{
printf( "内存分配失败\n" );
return 0;
}
else
{};
for(i=0;i<Row_X;i++)//
{
X[i]=(double*)calloc(Line_X,sizeof(double));
if( X[i] == NULL )
{
printf( "内存分配失败\n" );
return 0;
}
else
{};
for(j=0;j<Line_X;j++)
{
X[i][j]=i+j*j;
}
}
XT=Mat_tra(X,Row_X,Line_X);
//将X转置并复制到指针XT标识的内存中
Print_mat(X,Row_X,Line_X);
Print_mat(XT,Row_XT,Line_XT);
return 0;
}
--
FROM 111.193.233.*
好的,谢谢,学习了
【 在 z16166 的大作中提到: 】
: 没仔细看代码
: 我想说的是另外一个角度:
: 二维动态数组,也是可以用一维的数组来实现的,不需要进行二次的内存分配。
: ...................
--
FROM 111.193.233.*
好的,谢谢
子函数内分配内存有可能不知道主函数的内存规划,容易越界是吧?
【 在 ylh0315 的大作中提到: 】
: 都是必须的。
: 建议,不要在函数内分配内存。内存在函数外分配,用毕销毁。
: 最好是谁分配的谁负责销毁。
: ...................
--
FROM 111.193.233.*
好的,谢谢
代码质量差除了前面版友说的子函数内部分部内存外,还有其他什么毛病?我是新手,
想改进代码质量
【 在 longsword 的大作中提到: 】
: (1)if( AT == NULL )和if( AT[i] == NULL )都需要验证,不是多此一举,根本就是两回事。当然实际执行中==NULL很少,因为分配内存基本都能成功。
: (2)使用以前分配就可以。
: 结论是代码没有错误,但代码质量很差。
: ...................
--
FROM 111.193.233.*
好的,谢谢
【 在 liangf 的大作中提到: 】
: 建议用一重指针,在main里面把输入、输出的缓冲区都分配好作为参数传给子函数。
: 函数的参数,指针都加上 restrict,方便编译器优化。
: 不要用 // 格式的注释,一律用 /* */
: ...................
--
FROM 111.193.233.*
好的,收到
我学c的目的是想学嵌入式系统,好像嵌入式用C的人更多一些?
【 在 z16166 的大作中提到: 】
: 一、你这个代码其实是有内存泄漏的
: 下面这种“遇到失败就返回”的模式称为early return。
: if (xxx == NULL) {
: ...................
--
FROM 111.193.233.*
厉害了
【 在 forex 的大作中提到: 】
: Chatgpt校正版:
: #include <stdlib.h>
: #include <stdio.h>
: ...................
--
FROM 111.193.233.*
弱问一下什么是蛇形方式?没搜到
【 在 webhost 的大作中提到: 】
: 先把命名规范一下吧,c语言一般采用蛇形方式全小写加下划线。
--
FROM 111.193.233.*
去打开头文件看了一眼
确实都是按你说的写的:
__mingw_ovr
__attribute__((__format__ (gnu_printf, 1, 2))) __MINGW_ATTRIB_NONNULL(1)
int printf (const char *__format, ...)
{
register int __retval;
__builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
__retval = __mingw_vprintf( __format, __local_argv );
__builtin_va_end( __local_argv );
return __retval;
}
【 在 liangf 的大作中提到: 】
: 全小写,单词直接加下划线
--
FROM 111.193.233.*