遍历数组元素时获取 "Floating point exception (core dumped)"
Getting "Floating point exception (core dumped)" while iterating over array elements
我正在尝试获取前 10 个质数,但在编译时出现 浮点异常(核心已转储) 错误。
#include <stdio.h>
#define MAX 50
int main(void){
FILE * fp;
int i,j,cnt=0;
int prim[MAX]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
fp = fopen("primeros.dat", "wb");
do{
for (i=2; i<=100; i++){
for(j=0;j<=MAX;j++){
if (i%prim[j]==0){
continue;
}
else{
fwrite(&i, sizeof(int), 1, fp);
cnt++;
}
}
}
}while(cnt<10);
fclose(fp);
return 0;
}
问题出在所使用的循环条件和隐式初始化的数组元素的值中。这里要提两件事
1.多余的数组元素(当初始化列表提供的元素少于数组大小时)被初始化为 0。
引用 C11
,章节 §6.7.9
If there are fewer initializers in a brace-enclosed list than there are elements or members
of an aggregate, or fewer characters in a string literal used to initialize an array of known
size than there are elements in the array, the remainder of the aggregate shall be
initialized implicitly the same as objects that have static storage duration.
和..
[...] If an object that has static or thread storage duration is not initialized
explicitly, then:
- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
- if it is an aggregate, every member is initialized (recursively) according to these rules,
and any padding is initialized to zero bits; [...]
2。 C 数组具有从 0 开始的索引。
所以,在代码中
for(j=0;j<=MAX;j++)
问题是双重的。
使用有效条目后,您将面临i%prim[j]
中被零除的情况。这就是 FPE 的原因。
要解决此问题,您可以在定义时省略数组大小,稍后使用 sizeof
获取可用作循环条件的数组大小。
如果您有 MAX
有效 个元素,对于您的循环,当 j
变为 MAX
时,它超出了访问权限。它调用 undefined behavior.
你应该把它改成
for(j=0; j< MAX; j++)
保持在限制范围内。
for(j=0;j<=MAX;j++)
应该是
for(j=0;j<MAX;j++)
您的数组的有效访问是 prim[0]
到 prim[49]
,因此访问 prim[50]
是数组越界访问,会调用未定义的行为
奇怪的程序要求发现前 10 个素数,但已经包含前 20 个素数的数组。它还会导致除以 0 错误,因为 MAX
的 j
循环限制将导致数组中 0
值的索引(但无论如何都会越界 j == MAX
).
这个解决方案首先要知道只有 2
是质数。它构建素数数组,使用每个素数来测试更多数字的素数。
输出文件是二进制格式——我会输出到一个文本文件,但因为这不是主要问题,所以我在这个例子中只写了质数到控制台。
#include <stdio.h>
#define MAX 100
int main(void){
int i, j, cnt = 1;
int prim[MAX] = { 2 };
for(i=3; i<MAX; i++) {
for(j=0; j<cnt; j++) {
if(i % prim[j] == 0) {
break;
}
}
if(j == cnt) {
prim[cnt++] = i;
}
}
for(j=0; j<cnt; j++) {
printf("%4d", prim[j]);
}
printf("\n");
return 0;
}
程序输出:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97
这里是:
for(j=0; j<=MAX; j++){
你最多只能从 0 到 max-1 [0,max)
改为
for(j=0; j<MAX; j++){
我正在尝试获取前 10 个质数,但在编译时出现 浮点异常(核心已转储) 错误。
#include <stdio.h>
#define MAX 50
int main(void){
FILE * fp;
int i,j,cnt=0;
int prim[MAX]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71};
fp = fopen("primeros.dat", "wb");
do{
for (i=2; i<=100; i++){
for(j=0;j<=MAX;j++){
if (i%prim[j]==0){
continue;
}
else{
fwrite(&i, sizeof(int), 1, fp);
cnt++;
}
}
}
}while(cnt<10);
fclose(fp);
return 0;
}
问题出在所使用的循环条件和隐式初始化的数组元素的值中。这里要提两件事
1.多余的数组元素(当初始化列表提供的元素少于数组大小时)被初始化为 0。
引用 C11
,章节 §6.7.9
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
和..
[...] If an object that has static or thread storage duration is not initialized explicitly, then:
- if it has arithmetic type, it is initialized to (positive or unsigned) zero; - if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits; [...]
2。 C 数组具有从 0 开始的索引。
所以,在代码中
for(j=0;j<=MAX;j++)
问题是双重的。
使用有效条目后,您将面临
i%prim[j]
中被零除的情况。这就是 FPE 的原因。要解决此问题,您可以在定义时省略数组大小,稍后使用
sizeof
获取可用作循环条件的数组大小。如果您有
MAX
有效 个元素,对于您的循环,当j
变为MAX
时,它超出了访问权限。它调用 undefined behavior.你应该把它改成
for(j=0; j< MAX; j++)
保持在限制范围内。
for(j=0;j<=MAX;j++)
应该是
for(j=0;j<MAX;j++)
您的数组的有效访问是 prim[0]
到 prim[49]
,因此访问 prim[50]
是数组越界访问,会调用未定义的行为
奇怪的程序要求发现前 10 个素数,但已经包含前 20 个素数的数组。它还会导致除以 0 错误,因为 MAX
的 j
循环限制将导致数组中 0
值的索引(但无论如何都会越界 j == MAX
).
这个解决方案首先要知道只有 2
是质数。它构建素数数组,使用每个素数来测试更多数字的素数。
输出文件是二进制格式——我会输出到一个文本文件,但因为这不是主要问题,所以我在这个例子中只写了质数到控制台。
#include <stdio.h>
#define MAX 100
int main(void){
int i, j, cnt = 1;
int prim[MAX] = { 2 };
for(i=3; i<MAX; i++) {
for(j=0; j<cnt; j++) {
if(i % prim[j] == 0) {
break;
}
}
if(j == cnt) {
prim[cnt++] = i;
}
}
for(j=0; j<cnt; j++) {
printf("%4d", prim[j]);
}
printf("\n");
return 0;
}
程序输出:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
73 79 83 89 97
这里是:
for(j=0; j<=MAX; j++){
你最多只能从 0 到 max-1 [0,max)
改为
for(j=0; j<MAX; j++){