while(t=0)是怎么运行的?

int main()
{
    int m = 0;
    int n = 0;
    int t = 0;
    scanf("%d%d", &m, &n);//为什么这里输入18 24仍然可以得到最大公约数
    while (t = m%n)  18 %24不是等于0吗?
    {
        m = n;
        n = t;
    }
    printf("%d ", n);
    return 0;
}

18 %24不是等于0吗?
数学学的让人着急啊,18/24才是0,18%24还是18啊

18/24=0
18%24=18

18/24=0,除数
18%24=18,取余
另外:t = 0, 不是一个判别语句,而是一个赋值语句,其默认为Ture,因此会一直循环下去。
判别语句是 t==0, 要加两个等号

如果输入18 24,最后是不是变成t = 6%6 = 0,跳出循环,n = 6

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/7614907
  • 你也可以参考下这篇文章:C语言宏定义中出现的do...while(0)
  • 除此之外, 这篇博客: C语言 | 嵌入式中几个非常实用的宏技巧中的 do{}while(0) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:

    其实,上面我们封装的打印宏DBG_PRINTF还有一点缺陷,比如我们与if、else使用的时候,会有这样的一种使用情况:

    此时会报语法错误。为什么呢?

    同样的,我们可以先来看一下我们的demo代码预处理过后,相应的宏代码会被转换为什么。如:

    这里我们可以看到,我们的if、else结构代码被替换为如下形式:

    if(c)
    { /* ....... */ };
    else
    { /* ....... */ };
    

    显然,出现了语法错误。if之后的大括号之后不能加分号,这里的分号其实可以看做一条空语句,这个空语句会把if与else给分隔开来,导致else不能正确匹配到if,导致语法错误。

    为了解决这个问题,有几种方法。第一种方法是:把分号去掉。代码变成:

    第二种方法是:在if之后使用DBG_PRINTF打印调试时总是加{}。代码变成:

    以上两种方法都可以正常编译、运行了。

    但是,我们C语言中,每条语句往往以分号结尾;并且,总有些人习惯在if判断之后只有一条语句的情况下不加大括号;而且我们创建的DBG_PRINTF宏函数的目的就是为了对标printf函数,printf函数的使用加分号在任何地方的使用都是没有问题的。

    基于这几个原因,我们有必要再对我们的DBG_PRINTF宏函数进行一个改造。

    下面引入do{}while(0)来对我们的DBG_PRINTF进行一个简单的改造。改造后的DBG_PRINTF宏函数如下:

    #define DBG_PRINTF(fmt, args...)  \
    do\
    {\
        printf("<<File:%s  Line:%d  Function:%s>> ", __FILE__, __LINE__, __FUNCTION__);\
        printf(fmt, ##args);\
    }while(0)
    

    这里的do...while循环的循环体只执行一次,与不加循环是效果一样。并且,可以避免了上面的问题。预处理文件:

    我们的宏函数实体中,while(0)后面不加分号,在实际调用时补上分号,既符合了C语言语句分号结尾的习惯,也符合了do...while的语法规则。

    使用do{}while(0)来封装宏函数可能会让很多初学者看着不习惯,但必须承认的是,这确确实实是一种很常用的方法。

    在STM32的HAL库中搜索while(0):

    在Linux源码中搜索while(0):

    可见,在实际应用中,do{}while(0)用的很多。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^