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
不知道你这个问题是否已经解决, 如果还没有解决的话:其实,上面我们封装的打印宏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)用的很多。