gpt4 book ai didi

c - C中质数的平方

转载 作者:太空宇宙 更新时间:2023-11-04 00:22:09 24 4
gpt4 key购买 nike

我写的代码要求从键盘输入两个正整数第一个整数N在3-15范围内是奇数,第二个整数有一个初始值I。N是数组的大小。从整数I的NxN数组的中心开始。如果I是素数,则在正方形的该位置打印数字I。否则,在该位置打印三个星号。向右移一个正方形,测试整数I+1的素性。如果是素数,则打印I+1;如果不是,则打印三个星号继续逆时针穿过正方形,直到正方形充满数字和三个星号,然后打印数组。
这就是问题所在;我已经完成了大部分工作,并且对于如何创建数组以及是否有人可以查看我的代码以让我知道是否正确设置了for循环感到困惑谢谢你的帮助。

#include <stdio.h>

int main(int argc,char* argv[]) {
int N, I;

printf("Enter an odd integer n between 3 and 15: ");
scanf("%d", &N);

printf("Enter an initial value i: ");
scanf("%d", &I);

int arr[N][N];
int k = 1;
int i = N / 2 + 1;
int j = N / 2 + 1;

while(k < N) {
int s;

for(s = 0; s < k; s++, i++, I++)
arr[i][j] = IsPrime(I) ? I : -1;
for(s = 0; s < k; s++, j--, k++)
arr[i][j] = IsPrime(I) ? : -1;
k++;
for(s = 0; s < k; s++, i--, I++)
arr[i][j] = IsPrime(I) ? I : -1;
for(s = 0; s < k; s++, j++, I++)
arr[i][j] = IsPrime(I) ? I :-1;
arr[i][j] = IsPrime(I) ? I : -1;
k++;

if(IsPrime(i) == 1) {
return i;
} else {
printf("***");
}
}
return 0;
}

int IsPrime(int n) {
int i, count = 0;

for(i = 1; i <= n; i++) {
if((n % i) == 0) count++;
}
}

最佳答案

好吧,这里有很多错误,还有很多要解释的。让我们从真正明显的东西开始,阻止这甚至运行,然后继续。
我将使用C89,所以我将在每个方法的开头声明所有的局部变量我将使用gcc 4.6.1,并使用-W -Wall -ansi -pedantic -g -lm编译。
我们很快就需要-lm它链接到数学库。
伊斯普林()
因此,您的IsPrime(int n)似乎在底部缺少一些片段。因此,我甚至不能说它是否会起作用。
让我们把int IsPrime(int n);放在#include stdio.h下面的文件顶部来声明它当我们在做的时候,让我们再加上一些,包括:

#include <stdlib>
#include <math.h> /* For sqrt() */

现在,让我们用应该有效的方法替换方法的主体(好吧,您不必这样做,但我会这样做,因为我看不到您的方法的其余部分):
int IsPrime (int n) {
int i, sqrtN;

if (n < 2) { return 0; } /* 1, 0, and negatives are nonprime */
if (n == 2) { return 2; }
if ((n % 2) == 0) { return 0; } /* Check for even numbers */
sqrtN = sqrt(n) + 1; /* We don't need to search all the way up to n */
for (i = 3; i < sqrtN; i += 2) {
if (n % i == 0) { return 0; } /* Stop, because we found a factor! */
}
return n;
}

main()和scanf()
您没有使用参数来 main(),所以让我们将其更改为 int main(void) {
当您调用 scanf()时,您应该检查结果-它将返回成功匹配的项目数,或 EOF你还应该检查它存储的值,因为你需要N有一个特定的范围,而I是正的。
所以,让我们在 main()开始时尝试使用这个:
int N, I;
int s;
int i, j, k;
int **arr; /* More on this later*/

printf("Enter an odd integer n between 3 and 15: ");
s = scanf("%d", &N);
if (s != 1) {
printf("No proper input provided; program will now exit");
return 0; /* Or we could use EXIT_SUCCESS, which is defined by stdlib */
} else if (N < 3 || N > 15) {
/* I have assumed the range of 3 to 15 to be inclusive here */
printf("I must be positive; program will now exit");
return 0;
}

printf("Enter an initial value I: ");
s = scanf("%d", &I);
if (s != 1) {
printf("No proper input provided; program will now exit");
return 0;
} else if (I <= 0) {
printf("I must be positive; program will now exit");
return 0;
}

马洛克()
从对您的问题的评论中,您似乎了解到 malloc分配内存,但不一定要使用正确的语法在本例中进行分配。
这就是 int **arr;进入的地方要分配二维整数数组,现在我们有了N的合法值,可以执行 arr = malloc(N * sizeof arr[0]);
现在,malloc可能会失败,所以我们需要在调用之后检查 arr != NULL。我们还没结束呢!这只是数组的一维-我们刚刚为指向一维数组的N个指针分配了足够的内存,指向 arr
因此,我们必须循环并为这些指针分配空间。
所以我们这样做:
for (s = 0; s < N; ++s) {
arr[s] = malloc(N * sizeof arr[0][0]); /* Enough space for N integers */
if (NULL == arr[s]) {
/* We'll just quit instead of handling this gracefully... */
/* ...because this is only an example */
printf("Uh oh! Memory allocation failed! Let's run away!\n");
return 0;
}
}

自由()
现在,因为您已经分配了内存,所以当您用完内存时,还需要释放它在main方法的末尾,需要一个循环来释放为其分配空间的每个一维数组,然后需要释放 arr本身。
就像这样:
for (s = 0; s < N; ++s) {
free(arr[s]);
/* I am paranoid about setting pointers to NULL */
arr[s] = NULL;
}

free(arr);
arr = NULL;
/* It can matter if you are going on to do other things instead of exiting. */

return 0;

逻辑
所以,现在对于循环来说,它实际上意味着在数组中移动。
您将从main返回 i,而不是打印输出我很确定你打算把它打印出来,对吧?如果需要将整个网格作为一个网格打印出来,则需要在使用 IsPrime()测试所有值之后,在单独的过程中进行打印如果你只需要打印出这个数字是否是质数(好吧,这个数字或*),从中心开始呈螺旋状排列,那么你实际上根本不需要 arr
现在,你用来计算数字的循环也不正确(首先,它超出了数组的范围),但是我不愿意为你解决这个问题,因为这段逻辑是你作业的重点,所以试着先把我在这里提到的所有东西都整理一下,然后评论一下,如果你在那之后仍然坚持逻辑,我猜猜看。
顺便说一下,我避免改变你的变量名,但是你可能想考虑不要混合 Ii,并且通常更详细地命名事物。
螺旋逻辑
免责声明:也许有更好的方法,这正是我想到的不过,它确实有效。
我认为在中间的正方形和右边的正方形之间有一条边,在那个正方形和上面的正方形之间有另一条边,以此类推这形成了一个螺旋形的图案如果您绘制它,您还将注意到,在每一个第二个角点之后,下一个角点之前的边数将增加1(1,1,2,2,3,3)如果我们跟踪当前边的长度、需要更改的时间、要走的方向以及何时停止(我们知道总共有N*N个正方形,所以只需计算到目前为止您填写的正方形),那么这就相对简单了:
totalSquares = N * N;
currentSquare = 0;
currentSideLength = 1; /* Number of edges/transitions per side before we turn */
currentPositionOnSide = 0; /* How far down a side we are*/
increaseSideLength = 0; /* This keeps track of when to increase currentSideLength */
i = j = N / 2; /* The middle */
direction = 0; /* Which way we're going - using an enum here would be better for clarity */

while (currentSquare < totalSquares) {

arr[i][j] = IsPrime(I);
switch (direction) {
case 0: /* Right */
++j;
break;
case 1: /* Up */
--i;
break;
case 2: /* Left */
--j;
break;
case 3: /* Down */
++i;
break;
default: /* So we can see if something silly goes wrong with the direction! */
printf("WTH?\n");
break;
}

++currentSquare, ++I, ++currentPositionOnSide;

if (currentPositionOnSide == currentSideLength) { /* We're at a corner! */
++increaseSideLength; /* Keep track of the number of turns */
currentPositionOnSide = 0;
direction = (direction + 1) % 4; /* Wrap around */
if ((increaseSideLength % 2) == 0) { /* Increase every second corner */
++currentSideLength;
increaseSideLength = 0;
}
}
}

/* Ultra crude formatting - you may want to do better than this */
for (i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
if (arr[i][j] == 0) {
printf(" *** |");
} else {
printf("%4d |", arr[i][j]);
}
}
printf("\n");
}

现在,我已经检查过了,但是我还没有测试过!别这样-这是你的责任。另外,您显然需要添加这些变量或重用已有的一些变量(不过,我真的建议您使用命名良好的变量)
另外,通过让代码返回n或0(0不是素数,你说我必须是正的,所以不需要使用-1),这样就避免了所有的检查。

关于c - C中质数的平方,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8370936/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com