理解c中的%*d和if((scanf('quot;%d";,'n)!=1)|(n<;=0))

理解c中的%*d和if((scanf('quot;%d";,'n)!=1)|(n<;=0)),c,if-statement,conditional-statements,format-specifiers,C,If Statement,Conditional Statements,Format Specifiers,我必须用c语言打印这个图案 4 4 4 4 4 4 4 4 3 3 3 3 3 4 4 3 2 2 2 3 4 4 3 2 1 2 3 4 4 3 2 2 2 3 4 4 3 3 3 3 3 4 4 4 4 4 4 4 4 我发现这个代码和它有关 #include <stdio.h> #include <limits.h> #include <stdlib.h> int main() { while ( 1 ) {

我必须用c语言打印这个图案

4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
我发现这个代码和它有关

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main()  
{ 
    while ( 1 ) 
    { 
        printf( "Enter a non-negative number (0 - exit): " ); 

        int n; 

        if ( ( scanf( "%d", &n ) != 1 ) || ( n <= 0 ) ) break; 

        if ( INT_MAX / 2 < n )  
        { 
            n = INT_MAX / 2; 
        } 

        int width = 1; 

        for ( int tmp = n; tmp /= 10; ) ++width; 

        putchar( '\n' ); 

        int m = 2 * n - 1; 

        for ( int i = 0; i < m; i++ ) 
        { 
            for ( int j = 0; j < m; j++ ) 
            {
                int value1 = abs( n - i - 1 ) + 1;
                int value2 = abs( n - j - 1 ) + 1;

                printf( "%*d ", width, value1 < value2 ? value2 : value1 );
            } 
            putchar( '\n' ); 
        } 

        putchar( '\n' ); 
    } 

    return 0; 
 }
以及单格式说明符在这里接受两个值的方式

printf( "%*d ", width, value1 < value2 ? value2 : value1 );
printf(“%*d”,宽度,value1
为什么%和*一起使用
“%*d”

表达式
scanf(“%d”,&n)
将尝试将整数读入
n
,如果成功,将返回值
1
(实际上,它将返回成功读取的内容数,但是,由于您只要求一件事情,这是您最多可以得到的)。如果它失败,您将获得其他内容

因此,与
1
进行比较是为了确保它能正常工作。如果你没有得到
1
,那么一定是出了问题

语句
printf(“%d”,width,something)
实际上与
printf(“%5d”,something)
(它将打印至少五个字符宽的字段)密切相关,但不是固定的
5
,而是使用变量
width

因此,下面的两个
printf
调用是等效的:

int val = 42;
int wid = 5;
printf("%5d", val);
printf("%*d", wid, val);
由于在您给出的代码中,
width
似乎总是
1
,我不知道为什么会这样做。在我看来,只使用
%d
作为格式说明符会更容易


如果你对一个更简洁、更结构化的解决方案感兴趣,你可能会发现这很有帮助。如果这是教育性的工作,不要使用它,因为它的目的是要学会自己去做,但是看到另一种方法是很有帮助的

这段代码考虑了执行一行的逻辑,打印足够的元素,从最大值到一个,然后再次备份(但设置最小值以基于行打印)

然后,主代码只打印出足够的行,以便每行的中间值从最大值降到1,然后再次备份(基本上与每行使用的逻辑相同)

#包括
//代码打印出一行,从最大值到最小值,然后备份。
静态空心轮廓(int max,int min){
对于(int i=max;i>0;i--)printf(“%d”,i
返回

3如果输入错误,scanf函数返回宏EOF的值 在第一次转换(如果有)完成之前发生故障。 否则,scanf函数将返回分配的输入项的数量,该数量可以小于 早期匹配失败的事件

在这个if语句中

if (( scanf( "%d", &n ) != 1 ) || ( n <= 0 ));
格式转换说明符
%*d
指定输出字段的宽度(
*
)将设置为调用的参数(
width
),表达式
value1
选择这两个值
value1
value2
之间的最大值

您可以用以下方法重写此调用pf printf

if ( value1 < value2 )
{
    printf( "%*d ", width, value2 );
}
else
{
    printf( "%*d ", width, value1 );
}
if(值1<值2)
{
printf(“%*d”,宽度,值2);
}
其他的
{
printf(“%*d”,宽度,值1);
}

*
表示从参数中获取字段宽度,而不是将其硬编码为格式字符串。请参阅
pax> ./testProg

Enter a non-negative number (< 1 = exit): 2
2 2 2
2 1 2
2 2 2

Enter a non-negative number (< 1 = exit): 3
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3

Enter a non-negative number (< 1 = exit): 4
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4

Enter a non-negative number (< 1 = exit): -42
if (( scanf( "%d", &n ) != 1 ) || ( n <= 0 ));
printf( "%*d ", width, value1 < value2 ? value2 : value1 );
if ( value1 < value2 )
{
    printf( "%*d ", width, value2 );
}
else
{
    printf( "%*d ", width, value1 );
}