※ 引述《skyHuan (Huan)》之铭言:
: 在写程设矩阵乘法的题目的时候遇到一些问题
: 完整程式码在这里:https://pastebin.com/MxAUgHcY
: 这是执行结果:https://i.imgur.com/TWB7cYL.png
: 上面两区块是input,即一个2x3矩阵乘上一个3x4矩阵,最下面的区块是相乘完的结果
: 中间两个区块是测试过程,也就是我的问题所在
: 以下列出我的问题,基本的程式观念没有很好,还请前辈们多多指教
: 1. 我的作法是先宣告出要存相乘结果的矩阵并初始化,如程式第18行
: 我记得二维阵列可以用 = {0} 来把全部的内容初始化为0
: 但做完第18行后,print出新宣告的阵列结果会是测试区块的上面那块
: 出现几个很大的数字,感觉像是内存残值(?
: 用for循环重新设定每个为0之后才恢复正常全部都是0
: 是我 = {0} 的使用上有什么没注意到的吗
在 C 语言中只有阵列这个概念, 没有几维的分别. 当你用下面几种
方式来定义阵列, 概念上还是以巢状阵列为主 (array of arrays),
这个概念很重要, 尤其在算位移的时候:
int a[2]; // array of 2 ints
int b[3][4]; // array of 3 int[4]s
int c[4][5][6]; // array of 4 int[5][6]s
因此阵列元素 c[2] 的型别为 int[5][6], 内存位址为
(char*)&***c + 2 * sizeof(int[5][6])
^ ^ ^
第一个元素的位址 + 索引 * 每个元素的大小
另一个很重要的概念是: 阵列初始化只能初始前几个元素, 剩下未
给值的元素都将用 zero bytes 填满, 所以下面的初始化应该和你
所认知的不一样:
int a[3] = { -1 }; // { -1, 0, 0 }
一对大括号用来初始化一个阵列, 巢状阵列则需要有对应层数的大
括号来初始化:
int b[3][4] = {
{ -1 },
{ },
{ 5, 6, 7, 8 }
};
/*
b = {
{ -1, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 5, 6, 7, 8 }
}
*/
回到上一段所说的, 未给值的元素都会用 zero bytes 填满, 如果
你就想要全部值都填 0, 像初始化 b[1] 那样直接给空大括号即可
(全都不给初始值, 所以都用 zero bytes 来填).
: 2. 宣告二维阵列大小的时候,大小是否可以用变量来表示
: 例如程式码中的第7行中的m跟k1在scan后才能决定值
: 那第8行的二维阵列那样宣告是合法的吗,还是一定要用malloc的方式才行
: 我用自己电脑的IDE (CB)跟线上compiler (C99)跑都有过
: 但同学跑一模一样的程式码compiler不给过(VS)
可以, 但这需要你的编译器支援 VLA (Variable-Length Array),
这是在 C99 才进的 feature, 因为目前 C 编译器默认使用的语言
标准大多还是 C89/C90, 所以先确定你的编译器有支援到 C99 并在
编译时启用.
https://en.wikipedia.org/wiki/C99#Implementations
另外需要注意的是 VLA 的内存是放在 call stack 上, 使用的时
候小心别配置超过编译器/环境允许的大小.