【问题标题】:C - printing row and columnC - 打印行和列
【发布时间】:2021-05-10 21:18:21
【问题描述】:

请向我解释如何让程序在每次通过循环增加col时重置col

我想打印由LENGTH 控制的rowscols 的X 数量。

代码显然是一团糟,我不得不展开循环。我的问题是实际上如何正确循环???

实际上看起来很简单,但我真的无法理解它。 目前,我要做的就是将输出变为以下内容;

|----------------------------------------------------------------
| row: 0, col: 0| row: 0, col: 1| row: 0, col: 2| row: 0, col: 3|
|----------------------------------------------------------------
| row: 1, col: 0| row: 1, col: 1| row: 1, col: 2| row: 1, col: 3|
|----------------------------------------------------------------
| row: 2, col: 0| row: 2, col: 1| row: 2, col: 2| row: 2, col: 3|
|----------------------------------------------------------------
| row: 3, col: 0| row: 3, col: 1| row: 3, col: 2| row: 3, col: 3|
|----------------------------------------------------------------

到目前为止,它打印出来“一切都很好”(或多或少),但我写它的方式太愚蠢了,显然...... 是的,抱歉像隐士一样编码, 并感谢大家抽出宝贵的时间! 我绝对确定你知道如何做得更好,也许可以解释我在这里缺少什么。

干杯!

float LENGTH    = 0.0f;
int row = 0;
int col =0;

int main(int argc, char** argv)
{
    LENGTH = 8.0f;
    
    
    row = 0;
    col =0;
    
    for (;row < LENGTH; row++)
    {
        for (;col <= LENGTH; col++)
        {
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 1;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 2;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 3;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 4;
            col = 0;
            for (;row < GRID_LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 5;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 6;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 7;
            col = 0;
            for (;row < LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
            row = 8;
            col = 0;
            for (;row <= LENGTH; row++)
            {
                for (;col <= LENGTH; col++)
                {
                    printf("| r:%4i , c:%4i ", row, col);
                }
            }
            printf("\n");
        }
    }
    
    printf("\n");
    return 0;
}

c89 标签在那里,因为程序需要在该配置下运行。

原因是,我的计划是动态分配 多个向量。为此,我不想使用可变长度数组。

假设我们想要创建一个像棋盘或棋盘或类似性质的网格。网格应该以世界为中心(x=0,y=0,z=0)。 所以,如果网格只有LENGTH = 1,那么我们仍然需要 4 个向量来绘制 4 条线,至少要得到一个四边形...... 但是,如果函数的用户使用

LENGTH = 1,

那么我们需要在每个长度上加 1 (length +1) 这样当用户使用 LENGTH = 1 调用它时 我们实际上得到了至少 2x2 个向量。

在下面的代码中,我不确定是否应该将 vector 命名为 vector_array,因为我分配了所有我想要的向量。

size_t count = (((length +1) * (length +1)));
float *vector;
vector = NULL;
vector = calloc(count, sizeof(float) * 3);

我的问题是,如何分配向量数组,以及我们退出循环的位置,以便 rowcol 都像 row = -lengthcol = -length 一样被初始化

请忽略并原谅我,我交替使用了LENGTHlength。它们的意思是一样的,但应该使用LENGTH 将其初始化为 1...

    size_t LENGTH = 0;
    
    
    int main(int argc, const char * argv[])
    {
        LENGTH = 8;
        
        float *vector;
        vector = NULL;
        vector = calloc(3, sizeof(vector));
        if (vector == NULL)
        {
            printf("allocation of vector failed!\n");
            exit(0);
        }
        
        float **vector_array;
        vector_array = NULL;
        vector_array = calloc( ((LENGTH+1) * (LENGTH+1)), sizeof(vector));
        if (vector_array == NULL)
        {
            printf("allocation of vector array failed!\n");
            exit(0);
        }
        
        int row = 0;
        int col = 0;
        row = (int)-LENGTH;
        col = (int)-LENGTH;
        
        while (row < (int)LENGTH)
        {
            while (col < (int)LENGTH)
            {
                vector_array[row] = row;
                vector_array[col] = col;
                col++;
            }
            row++;
        }
        
        row = (int)-LENGTH;
        col = (int)-LENGTH;
        while (row <= (int)LENGTH)
        {
            
            while (col <= (int)LENGTH)
            {
                printf("c:%d\n", vector_array[col]);
                col++;
            }
            printf("r:%d\n", vector_array[row]);
            row++;
        }
        return 0;
    }

我无法更好地解释我尝试做的事情。 我是一个初学者,我把C作为一种爱好......

非常感谢!

【问题讨论】:

  • 如果代码正常工作并且您需要反馈或改进建议,那么将问题发布到Code Review 会更合适。如果您有特定问题(例如不正确的输出),请更新问题以提供确切问题的详细信息。
  • 如何让程序在每次循环时为我进行重置。我想打印由长度控制的 X 行和列。代码显然是一团糟。我不得不展开循环。我的问题是实际上如何正确循环???
  • 展开从未存在过的循环,即...
  • Edit提供任何更新信息的问题。
  • 您为什么将问题标记为 C89?这是故意的吗?您使用的是 30 年前的语言版本吗?

标签: c c89


【解决方案1】:

您的循环嵌套到四个级别。这是不必要的。您应该只需要两层嵌套。外循环的每次迭代都应该处理一行,内循环的每次迭代都应该处理该行的一列。

一般情况下,您不应在if 语句之外修改循环计数器,因为这可能会使您的代码混乱且难以理解。只有在极少数情况下这是合适的(这不是其中之一)。

此外,将整数与浮点数进行比较通常不是一个好主意,因为浮点数的精度有限。因此,它们通常不会完全相等,并且比较会失败。例如,如果将整数76.99999999998 进行比较,则比较的结果可能为假,尽管数字实际上是相等的。在比较浮点值时,通常应该允许一定的容差,例如通过确定两个值之间的差异是否超过某个阈值。

这是一个符合 C89 标准的循环问题解决方案:

#include <stdio.h>

#define NUM_ROWS 4
#define NUM_COLS 4

int main( void )
{
    int row, col;

    for ( row = 0; row < NUM_ROWS; row++ )
    {
        // print first line containing only a static horizontal bar
        printf( "|" );
        for ( col = 0; col < NUM_COLS; col++ )
            printf( "-----------------" );
        printf( "\n" );

        //print second line containing the variable information
        for ( col = 0; col < NUM_COLS; col++ )
            printf( "| row: %i, col: %i ", row, col );

        //print vertical bar at end of line
        printf( "|\n" );
    }

    //print static horizontal bar
    printf( "|" );
    for ( col = 0; col < NUM_COLS; col++ )
        printf( "-----------------" );
    printf( "\n" );

    return 0;
}

上面的代码唯一不符合 C89 的是单行 cmets (//)。如果您想要严格遵守 C89,您可能必须用多行 cmets(/**/)替换它们。但是,大多数 C89 编译器都接受单行 cmets 作为语言扩展。

上面的代码包含一些代码重复。可以通过从外部循环内部中断来删除此代码重复,如下所示:

#include <stdio.h>

#define NUM_ROWS 4
#define NUM_COLS 4

int main( void )
{
    int row, col;

    //NOTE: Leaving out the middle expression of the "for" statement
    //      will make it always true.
    for ( row = 0; ; row++ )
    {
        // print first line containing only a static horizontal bar
        printf( "|" );
        for ( col = 0; col < NUM_COLS; col++ )
            printf( "-----------------" );
        printf( "\n" );

        //break out of loop, if past last row
        if ( row == NUM_ROWS )
            break;

        //print second line containing the variable information
        for ( col = 0; col < NUM_COLS; col++ )
            printf( "| row: %i, col: %i ", row, col );

        //print vertical bar at end of line
        printf( "|\n" );
    }

    return 0;
}

代码现在更短(如果您忽略附加注释),但可能有点难以理解。

这两个程序都打印以下输出:

|--------------------------------------------------------------------
| row: 0, col: 0 | row: 0, col: 1 | row: 0, col: 2 | row: 0, col: 3 |
|--------------------------------------------------------------------
| row: 1, col: 0 | row: 1, col: 1 | row: 1, col: 2 | row: 1, col: 3 |
|--------------------------------------------------------------------
| row: 2, col: 0 | row: 2, col: 1 | row: 2, col: 2 | row: 2, col: 3 |
|--------------------------------------------------------------------
| row: 3, col: 0 | row: 3, col: 1 | row: 3, col: 2 | row: 3, col: 3 |
|--------------------------------------------------------------------

请注意,如果数字大于 10,格式将不再正常工作,因为它们将需要更多空间。


关于如何计算绘制二维网格所需的线的第二个问题:

如果要绘制10*10 平铺网格的线,则需要绘制 11 条水平线和 11 条垂直线。您可以使用以下逻辑生成这些线的坐标:

#include <stdio.h>

#define PIXELS_PER_TILE 50
#define SIZE_X 10
#define SIZE_Y 10

int main( void )
{
    int i;

    printf( "Processing lines along X axis:\n" );
    for ( i = 0; i <= SIZE_Y; i++ )
    {
        printf(
            "Draw line from [%3d,%3d] to [%3d,%3d]\n",
            0      * PIXELS_PER_TILE, i * PIXELS_PER_TILE,
            SIZE_X * PIXELS_PER_TILE, i * PIXELS_PER_TILE
        );
    }

    printf( "\nProcessing lines along Y axis:\n" );
    for ( i = 0; i <= SIZE_X; i++ )
    {
        printf(
            "Draw line from [%3d,%3d] to [%3d,%3d]\n",
            i * PIXELS_PER_TILE, 0      * PIXELS_PER_TILE,
            i * PIXELS_PER_TILE, SIZE_Y * PIXELS_PER_TILE
        );
    }
}

这是该程序的输出:

Processing lines along X axis:
Draw line from [  0,  0] to [500,  0]
Draw line from [  0, 50] to [500, 50]
Draw line from [  0,100] to [500,100]
Draw line from [  0,150] to [500,150]
Draw line from [  0,200] to [500,200]
Draw line from [  0,250] to [500,250]
Draw line from [  0,300] to [500,300]
Draw line from [  0,350] to [500,350]
Draw line from [  0,400] to [500,400]
Draw line from [  0,450] to [500,450]
Draw line from [  0,500] to [500,500]

Processing lines along Y axis:
Draw line from [  0,  0] to [  0,500]
Draw line from [ 50,  0] to [ 50,500]
Draw line from [100,  0] to [100,500]
Draw line from [150,  0] to [150,500]
Draw line from [200,  0] to [200,500]
Draw line from [250,  0] to [250,500]
Draw line from [300,  0] to [300,500]
Draw line from [350,  0] to [350,500]
Draw line from [400,  0] to [400,500]
Draw line from [450,  0] to [450,500]
Draw line from [500,  0] to [500,500]

如果要绘制10*10*10 平铺网格(即3D 网格)的线,则需要沿X 轴绘制11*11 线,沿Y 轴绘制11*11 线,和11*11 沿 Z 轴的线(共 363 条线)。您可以使用以下逻辑生成这些线的坐标:

#include <stdio.h>

#define PIXELS_PER_TILE 50
#define SIZE_X 10
#define SIZE_Y 10
#define SIZE_Z 10

int main( void )
{
    int i;
    int j;

    printf( "Processing lines along X axis:\n" );
    for ( i = 0; i <= SIZE_Y; i++ )
    {
        for ( j = 0; j <= SIZE_Z; j++ )
        {
            printf(
                "Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
                0      * PIXELS_PER_TILE, i * PIXELS_PER_TILE, j * PIXELS_PER_TILE,
                SIZE_X * PIXELS_PER_TILE, i * PIXELS_PER_TILE, j * PIXELS_PER_TILE
            );
        }
    }

    printf( "\nProcessing lines along Y axis:\n" );
    for ( i = 0; i <= SIZE_X; i++ )
    {
        for ( j = 0; j <= SIZE_Z; j++ )
        {
            printf(
                "Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
                i * PIXELS_PER_TILE, 0      * PIXELS_PER_TILE, j * PIXELS_PER_TILE,
                i * PIXELS_PER_TILE, SIZE_Y * PIXELS_PER_TILE, j * PIXELS_PER_TILE
            );
        }
    }

    printf( "\nProcessing lines along Z axis:\n" );
    for ( i = 0; i <= SIZE_X; i++ )
    {
        for ( j = 0; j <= SIZE_Y; j++ )
        {
            printf(
                "Draw line from [%3d,%3d,%3d] to [%3d,%3d,%3d]\n",
                i * PIXELS_PER_TILE, j * PIXELS_PER_TILE, 0      * PIXELS_PER_TILE,
                i * PIXELS_PER_TILE, j * PIXELS_PER_TILE, SIZE_Z * PIXELS_PER_TILE
            );
        }
    }
}

我不会发布第二个程序的输出,因为它会打印数百行输出。

【讨论】:

  • 非常感谢!!真正的救星!!我还没有测试代码,但我现在就用它做实验!!感谢一千倍的人!
  • @Nickname:请注意,我刚刚修复了我发布的第二个代码中的一个错误(较短的那个)。请不要使用我的旧代码。
  • 再次感谢您!言语无法形容我现在的感激之情。两天我和这些东西打了一架,犹豫了很久才在这里陈述我的问题......好吧,特别感谢大家,安德烈亚斯
  • @Nickname 如果你喜欢这个答案,也可以考虑投票
猜你喜欢
  • 2021-11-09
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2016-05-01
  • 2017-04-03
  • 1970-01-01
相关资源
最近更新 更多