在C中存储和打印数组
Storing and printing array in C
我正在研究 C 语言的结构和算法,我已经花了好几个小时试图理解这个例子。
如果有人能简单地向我解释一下,我将非常高兴,因为它显然在我的头顶上飞来飞去,我光滑的大脑无法理解它。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <errno.h>
#include <string.h>
#define r(i,j) r[(i)*n+(j)]
int main()
{
int *p, n, pom, i, j;
long *r;
FILE *d;
d = fopen ("niz", "r");
if (d == NULL)
perror("Ne mogu otvoriti datoteku");
for (n = 0; fscanf(d, "%d", &pom) == 1; n++);
fseek (d, 0L, SEEK_SET);
p = (int *) malloc (n * sizeof (int));
if (p == NULL)
perror("Nema dovoljno memorije za ucitati niz");
for (n = 0; fscanf(d, "%d", &p[n]) == 1; n++);
fclose (d);
if ((r = (long *) malloc (n*n*sizeof(long))) == NULL)
perror("Nema dovoljno memorije za rezultat");
for (j = 0; j < n; j++)
{
r(0,j) = p[j];
for (i = 1; i < n; i++)
r(i,j) = r(i-1,j) * r(0,j);
}
free (p);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf ("%10ld", r(i,j));
printf ("\n");
}
d = fopen ("matrica", "wb");
fwrite (&n, sizeof (int), 1, d);
fwrite (r, sizeof (long), n*n, d);
fclose (d);
free (r);
return 0;
}
这基本上就是这段代码的作用,它从文件中读取几个数字,存储它们,然后将其打印在给定数组中的屏幕上。
所以我在这里不明白#define 块是如何工作的,我们只用最简单的术语(例如#define AGE 12)教过它是如何工作的,甚至从未在其中进行计算。
现在除此之外,在代码末尾有 2 个 for 循环块,一个存储值,一个打印它们,现在我要是能理解它是如何做到的就好了。
我试过打印它存储的数字,对于变量 'j' 我得到正确的数字,从 1 到 6,当我打印 r(i,j) 我得到 0 或随机高数,所以基本上我甚至不明白它是如何计算它们的,或者根本不明白#define 中的公式与它有什么关系。
我将不胜感激任何形式的帮助,因为我现在看这段代码太久了,此时我的大脑感觉太流畅了,因为我不理解它。
可以看出,最新的打印数字的 for 循环工作得很好,但在它上面我放了 2 个 printf 函数来检查数字是否匹配并弄清楚它是如何工作的,但我想不通完全没有。
变量 'j' 正在打印出 6 个数字,尽管是从 0 到 5,但在下面它打印的是从 1 到 6,但基本上它是可行的,我理解那个。
就在它下面变量 'r' 正在打印 0 或一些随机的高数字,但是当它在最新的块中打印它时,它应该这样做,而这个我根本无法理解.
#define AGE 12
和 #define r(i,j) r[(i)*n+(j)]
的工作方式相同。
在你的程序中,匹配AGE
的代码将被替换为12
,同理,匹配r(i,j)
的代码将被替换为r[(i)*n+(j)]
,i
和 j
是作为类函数宏的参数传递的值。
假设i
是1,j
是2,n
是5,r(i,j) = r(i-1,j) * r(0,j)
相当于:
r[(1)*5 + (1)] = r[(1-1)*5 + (2)] * r[(0)*5 + (2)]
将达到:
r[6] = r[2] + r[2]
索引为 6 的数组元素将被赋予索引为 2 的数组元素中存储的值的总和的结果。
关于函数的作用,它只是将一维数组用作二维数组的数组算术,避免了使用实际二维数组来 store/print 值的需要。
如果将打印循环替换为:
for (i = 0; i < n * n; i++) {
printf("%10ld", r[i]);
}
您会看到相同的值,但打印为一维数组,这就是它的本来面目。
打印出来的看似随机的数字,只是一个提示,表明您正在访问超出其边界的数组,从而调用未定义的行为。
我正在研究 C 语言的结构和算法,我已经花了好几个小时试图理解这个例子。 如果有人能简单地向我解释一下,我将非常高兴,因为它显然在我的头顶上飞来飞去,我光滑的大脑无法理解它。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <errno.h>
#include <string.h>
#define r(i,j) r[(i)*n+(j)]
int main()
{
int *p, n, pom, i, j;
long *r;
FILE *d;
d = fopen ("niz", "r");
if (d == NULL)
perror("Ne mogu otvoriti datoteku");
for (n = 0; fscanf(d, "%d", &pom) == 1; n++);
fseek (d, 0L, SEEK_SET);
p = (int *) malloc (n * sizeof (int));
if (p == NULL)
perror("Nema dovoljno memorije za ucitati niz");
for (n = 0; fscanf(d, "%d", &p[n]) == 1; n++);
fclose (d);
if ((r = (long *) malloc (n*n*sizeof(long))) == NULL)
perror("Nema dovoljno memorije za rezultat");
for (j = 0; j < n; j++)
{
r(0,j) = p[j];
for (i = 1; i < n; i++)
r(i,j) = r(i-1,j) * r(0,j);
}
free (p);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf ("%10ld", r(i,j));
printf ("\n");
}
d = fopen ("matrica", "wb");
fwrite (&n, sizeof (int), 1, d);
fwrite (r, sizeof (long), n*n, d);
fclose (d);
free (r);
return 0;
}
这基本上就是这段代码的作用,它从文件中读取几个数字,存储它们,然后将其打印在给定数组中的屏幕上。
所以我在这里不明白#define 块是如何工作的,我们只用最简单的术语(例如#define AGE 12)教过它是如何工作的,甚至从未在其中进行计算。
现在除此之外,在代码末尾有 2 个 for 循环块,一个存储值,一个打印它们,现在我要是能理解它是如何做到的就好了。 我试过打印它存储的数字,对于变量 'j' 我得到正确的数字,从 1 到 6,当我打印 r(i,j) 我得到 0 或随机高数,所以基本上我甚至不明白它是如何计算它们的,或者根本不明白#define 中的公式与它有什么关系。
我将不胜感激任何形式的帮助,因为我现在看这段代码太久了,此时我的大脑感觉太流畅了,因为我不理解它。
可以看出,最新的打印数字的 for 循环工作得很好,但在它上面我放了 2 个 printf 函数来检查数字是否匹配并弄清楚它是如何工作的,但我想不通完全没有。
变量 'j' 正在打印出 6 个数字,尽管是从 0 到 5,但在下面它打印的是从 1 到 6,但基本上它是可行的,我理解那个。
就在它下面变量 'r' 正在打印 0 或一些随机的高数字,但是当它在最新的块中打印它时,它应该这样做,而这个我根本无法理解.
#define AGE 12
和 #define r(i,j) r[(i)*n+(j)]
的工作方式相同。
在你的程序中,匹配AGE
的代码将被替换为12
,同理,匹配r(i,j)
的代码将被替换为r[(i)*n+(j)]
,i
和 j
是作为类函数宏的参数传递的值。
假设i
是1,j
是2,n
是5,r(i,j) = r(i-1,j) * r(0,j)
相当于:
r[(1)*5 + (1)] = r[(1-1)*5 + (2)] * r[(0)*5 + (2)]
将达到:
r[6] = r[2] + r[2]
索引为 6 的数组元素将被赋予索引为 2 的数组元素中存储的值的总和的结果。
关于函数的作用,它只是将一维数组用作二维数组的数组算术,避免了使用实际二维数组来 store/print 值的需要。
如果将打印循环替换为:
for (i = 0; i < n * n; i++) {
printf("%10ld", r[i]);
}
您会看到相同的值,但打印为一维数组,这就是它的本来面目。
打印出来的看似随机的数字,只是一个提示,表明您正在访问超出其边界的数组,从而调用未定义的行为。