我应该将赋值放在 for 循环中还是不在循环中?
Should I put an assignment in the for loop or out of it?
#include <stdio.h>
void print1(int m, int n, double (*p)[m][n]);
void print2(int m, int n, double (*p)[m][n]);
void print3(int m, int n, double (*p)[m][n]);
void print4(int m, int n, double (*p)[m][n]);
void print5(int m, int n, double (*p)[m][n]);
int main(void)
{
double a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
print1(3, 2, &a);
print2(3, 2, &a);
print3(3, 2, &a);
print4(3, 2, &a);
print5(3, 2, &a);
return 0;
}
void print1(int m, int n, double (*p)[m][n])
{
double subTotal;
subTotal = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print2(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0, subTotal = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print3(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
subTotal = 0;
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print4(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
for (int j = 0, subTotal = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print5(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal = 0;
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
看上面的代码。我写了五个C函数,分别是print 1 ~ print 5.
它们之间唯一的区别是subTotal = 0
的位置
对我来说, print1 、 print3 和 print5 很容易理解。
我预计 print2 与 print1 相同,print4 与 print3 相同。
但结果证明我错了。这是输出:
1.000000~~~4.000000~~~9.000000~~~
11.000000~~~15.000000~~~21.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~4.000000~~~9.000000~~~
2.000000~~~6.000000~~~12.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~3.000000~~~5.000000~~~
2.000000~~~4.000000~~~6.000000~~~
******************
我想不通为什么 print2 和 print4 打印的结果与我的预期不同。
为什么我理解错了?
这里 for(int i = 0, subTotal = 0; ...
在循环的 init 语句中定义了 两个 变量。第一个是 int i
,第二个是 int subTotal
,它隐藏函数顶部的 double subTotal
(不使用它)。
因此,print2
和 print4
使用 %lf
格式说明符来打印整数,这是未定义的行为。
添加 -Wall -Wextra -Wshadow
to GCC 会对所有这些效果产生警告。
关于为什么print2和print4打印0的问题:
您正在使用 %lf
格式说明符打印 for
循环的局部整数 subtotal
。
C 委员会关于 printf
和 fprintf
的草案指出:
7.21.6 Formatted input/output functions
...
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is
undefined.
#include <stdio.h>
void print1(int m, int n, double (*p)[m][n]);
void print2(int m, int n, double (*p)[m][n]);
void print3(int m, int n, double (*p)[m][n]);
void print4(int m, int n, double (*p)[m][n]);
void print5(int m, int n, double (*p)[m][n]);
int main(void)
{
double a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
print1(3, 2, &a);
print2(3, 2, &a);
print3(3, 2, &a);
print4(3, 2, &a);
print5(3, 2, &a);
return 0;
}
void print1(int m, int n, double (*p)[m][n])
{
double subTotal;
subTotal = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print2(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0, subTotal = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print3(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
subTotal = 0;
for (int j = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print4(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
for (int j = 0, subTotal = 0; j < m; j++) {
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
void print5(int m, int n, double (*p)[m][n])
{
double subTotal;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
subTotal = 0;
subTotal += (*p)[j][i];
printf("%lf~~~", subTotal);
}
printf("\n");
}
printf("******************\n");
}
看上面的代码。我写了五个C函数,分别是print 1 ~ print 5.
它们之间唯一的区别是subTotal = 0
的位置对我来说, print1 、 print3 和 print5 很容易理解。
我预计 print2 与 print1 相同,print4 与 print3 相同。
但结果证明我错了。这是输出:
1.000000~~~4.000000~~~9.000000~~~
11.000000~~~15.000000~~~21.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~4.000000~~~9.000000~~~
2.000000~~~6.000000~~~12.000000~~~
******************
0.000000~~~0.000000~~~0.000000~~~
0.000000~~~0.000000~~~0.000000~~~
******************
1.000000~~~3.000000~~~5.000000~~~
2.000000~~~4.000000~~~6.000000~~~
******************
我想不通为什么 print2 和 print4 打印的结果与我的预期不同。
为什么我理解错了?
这里 for(int i = 0, subTotal = 0; ...
在循环的 init 语句中定义了 两个 变量。第一个是 int i
,第二个是 int subTotal
,它隐藏函数顶部的 double subTotal
(不使用它)。
因此,print2
和 print4
使用 %lf
格式说明符来打印整数,这是未定义的行为。
添加 -Wall -Wextra -Wshadow
to GCC 会对所有这些效果产生警告。
关于为什么print2和print4打印0的问题:
您正在使用 %lf
格式说明符打印 for
循环的局部整数 subtotal
。
C 委员会关于 printf
和 fprintf
的草案指出:
7.21.6 Formatted input/output functions
...
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.