最终编辑
在调试此代码时,我会看到第一个循环行执行n
次,但下面的行只执行一次。不过,直到后来我才注意到,预期的值实际上正在发生变化:这只是一次执行了循环线,就好像循环在一个步骤中完成了所有迭代一样。从第二个循环开始,按下F10(我使用VSCode(将直接跳到下一个循环,而不是跳到下个迭代。这就是编译器的行为(MinGW64(。
现在,格式化循环如下:
for( ; x<n; x++) {
p[y][x] = h;
} x--;
for( ; y<n; y++) {
p[y][x] = h;
} y--;
etc...
确实导致每个迭代都被单独读取:现在从第二个循环开始,按下F10只会跳到下一个迭代,而不是直接跳到下个循环
结论:两种样式的工作方式相同,但调试方式不同。
不管怎样,这里有一个版本仍然很难看,但现在可以像预期的那样工作:
#include <stdio.h>
int main(){
int n,size,sqrs,start=0,h,y,x; scanf("%i",&n);
int p[n][n];
size = n;
if(n%2==0) sqrs = n/2;
else sqrs = n/2+1;
h = 1;
y = start;
x = start;
for(int t=0; t<sqrs; t++){
for( ; x<n; x++) p[y][x] = h; x--;
for( ; y<n; y++) p[y][x] = h; y--;
for( ; x>=start; x--) p[y][x] = h; x++;
for( ; y>=start; y--) p[y][x] = h; y++;
y++; x++; h++; start++; n--;
}
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
printf("%i ",p[i][j]);
} printf("n");
}
}
编辑:
我试图建立一个矩阵,其中数字向中心增长,即"金字塔"。到目前为止,我还没有遇到任何问题,在C中对循环使用一行语句。现在,将它们连续放置会导致它们被跳过,除了第一个循环。在我看来,我们有一个"for"循环,然后是它的单个语句,然后是分号,它应该(至少,我希望它(终止这一行,然后转到下一段代码,这恰好是另一个"for"循环。问题是第一个"for"循环按预期运行,然而,以下循环只是被跳过,因为它们处于结束状态。我强调";不嵌套";因为:
- 在搜索这个问题时,我所找到的只是关于嵌套循环和if语句,这些语句涉及使用或不使用大括号
- 每个for循环/语句都以分号结尾
我尝试过支撑单个语句,但它并没有解决问题
不过,解决问题的是添加大括号和换行符,如下所示:
for( ; y<n; y++) {
p[y][x] = h;
}
但是,在这种情况下,我仍然不知道为什么C中需要这些,这让我很困扰。例如,在调试时,我注意到第二个循环被跳过,因为y
的值从0
变为4
。这一点对我来说已经是个谜了。
顺便说一句,我很抱歉含糊其辞!
原始帖子:
这是我的代码:
#include <stdio.h>
int main(){
int n,sqrs,start=0,h,y,x; scanf("%i",&n);
int p[n][n];
if(n%2==0) sqrs = n/2;
else sqrs = n/2+1;
h = 1;
y = start;
x = start;
for(int t=0; t<sqrs; t++){
for( ; x<n; x++) p[y][x] = h; // THESE LOOPS
for( ; y<n; y++) p[y][x] = h; // here, y changes from 0 to 4
for( ; x>=start; x--) p[y][x] = h;
for( ; y>=start; y--) p[y][x] = h;
y++; x++; h++; start++; n-=2;
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
printf("%i",p[i][j]);
} printf("n");
}
}
正如您所看到的,这些循环不是嵌套的。如果他们之间没有任何声明,他们会嵌套,但确实存在
因此,第一个迭代正常,但以下所有迭代都不正常。他们只是跳过
我确实设法绕过了这一点,但奇怪的是,只有当我添加了大括号和换行符时,即所有循环(除了第一个循环,它似乎不需要它(看起来都是这样的:
for( ; y<n; y++) {
p[y][x] = h;
}
这对我来说仍然是个谜。当然,如果这是重复的,我很抱歉。我只是找不到任何关于这方面的具体信息。
编辑:正如你们中的一些人所注意到的那样,是的,我正在努力打印一个";"金字塔";矩阵我之所以没有提到它,是因为对我来说,这个问题只是关于语法,而不是那么相关。
从OP代码或描述中都不清楚您想要实现什么。
根据最近SO的另一个问题,也许这就是你所寻求的。这利用了(我相信(所需输出的对称性。在每次迭代中分配四个阵列元素,直到到达图案的中心。
int main() {
const uint8_t n = 9;
uint8_t mat[n][n];
for( int r = 0; r < (n+1)/2; r++ )
for( int c = 0; c < (n+1)/2; c++ )
mat[r ][c ] =
mat[n-1-r][c ] =
mat[r ][n-1-c] =
mat[n-1-r][n-1-c] =
1 + (c<r?c:r);
for( int i = 0; i < n; i++ ) {
for( int j = 0; j < n; j++ )
printf("%d ", mat[i][j]);
puts( "" );
}
return 0;
}
1 1 1 1 1 1 1 1 1
1 2 2 2 2 2 2 2 1
1 2 3 3 3 3 3 2 1
1 2 3 4 4 4 3 2 1
1 2 3 4 5 4 3 2 1
1 2 3 4 4 4 3 2 1
1 2 3 3 3 3 3 2 1
1 2 2 2 2 2 2 2 1
1 1 1 1 1 1 1 1 1
也许";不嵌套";是标准吗?
int main() {
const uint8_t n = 9, h = ((n+1)/2); // 'h'alf way
uint8_t mat[n][n];
for( int x = 0; x < h*h; x++ ) {
int r0 = x / h, r1 = n-1-r0; // top & bottom rows of this square
int c0 = x % h, c1 = n-1-c0; // left & right cols of this square
uint8_t v = 1 + ( c0 < r0 ? c0 : r0 );
mat[r0][c0] = mat[r0][c1] =
mat[r1][c0] = mat[r1][c1] = v;
}
/* same nested output loops */
return 0;
}
您的代码中有多个错误:
- 您应该在每个内部循环之后撤消最后一个增量/减量。按照编码,将
h
存储在数组p
的末尾之外 n
应仅递减1
- 由于
n
被修改,所以最后的循环没有影响
这是一个修改后的版本,保持你的老掉牙风格:
#include <stdio.h>
int main(){
int n,sqrs,start=0,end,h,y,x; scanf("%i",&n);
int p[n][n];
if(n%2==0) sqrs = n/2;
else sqrs = n/2+1;
h = 1;
y = start;
x = start;
end = n;
for(int t=0; t<sqrs; t++){
for( ; x<end; x++) p[y][x] = h; x--;
for( ; y<end; y++) p[y][x] = h; y--;
for( ; x>=start; x--) p[y][x] = h; x++;
for( ; y>=start; y--) p[y][x] = h; y++;
y++; x++; h++; start++; end--;
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
printf("%i",p[i][j]);
} printf("n");
}
}
此代码可以简化为:
#include <stdio.h>
int main(){
int n; scanf("%i",&n);
int p[n][n];
int h=1,start=0,stop=n-1;
for(int t=0; t<n; t+=2,h++,start++,stop--){
int x=start,y=start; p[y][x] = h;
while(x<stop) p[y][x++] = h;
while(y<stop) p[y++][x] = h;
while(x>start) p[y][x--] = h;
while(y>start) p[y--][x] = h;
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) printf("%i",p[i][j]);
printf("n");
}
}
这里有一个更经典的版本:
#include <stdio.h>
int main() {
int n;
if (scanf("%i", &n) != 1 || n <= 0)
return 1;
int p[n][n];
int h = 1, start = 0, stop = n - 1;
for (int t = 0; t < n; t += 2, h++, start++, stop--) {
int i = start, j = start;
if (start == stop)
p[i][j] = h;
for (; j < stop; j++)
p[i][j] = h;
for (; i < stop; i++)
p[i][j] = h;
for (; j > start; j--)
p[i][j] = h;
for (; i > start; i--)
p[i][j] = h;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
printf("%i", p[i][j]);
printf("n");
}
return 0;
}
请注意,您可以直接计算数组值,而不是跟踪连续的正方形:
#include <stdio.h>
int min(int a, int b) { return a < b ? a : b; }
int main() {
int n, i, j;
if (scanf("%i", &n) != 1 || n <= 0)
return 1;
char p[n][n + 1];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++)
p[i][j] = '1' + min(min(i, j), min(n - i - 1, n - j - 1));
p[i][j] = 'n';
}
printf("%.*s", (int)sizeof(p), &p[0][0]);
return 0;
}
您似乎正在尝试在矩阵中创建一个同心框的模式。你的逻辑是错误的。下面是一个使用Ada编程语言的示例。把它翻译成C应该很容易。
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
type matrix is array (Positive range <>, Positive range <>) of Positive;
Side : Positive;
begin
Put ("Enter the number of elements on a side of the array: ");
Get (Side);
declare
Box : matrix (1 .. Side, 1 .. Side);
Center : Positive;
Start : Positive := 1;
Stop : Positive := Side;
Value : Positive := 1;
begin
Center := (if Side mod 2 = 0 then side / 2 else side / 2 + 1);
for turn in 1 .. Center loop
-- sides
for I in Start .. Stop loop
Box (Start, I) := Value;
Box (I, Start) := Value;
Box (Stop, I) := Value;
Box (I, Stop) := Value;
end loop;
-- adjust for inner box values
Start := Start + 1;
Stop := Stop - 1;
Value := Value + 1;
end loop;
for I in Box'Range (1) loop
for J in Box'Range (2) loop
Put (Item => Box (I, J), Width => 1);
end loop;
New_Line;
end loop;
end;
end Main;
示例执行的输出为:
Enter the number of elements on a side of the array: 7
1111111
1222221
1233321
1234321
1233321
1222221
1111111