C 宏语法引起的错误
我看到了下面的代码,其中一小部分没有意义,因为这超出了我目前的知识范围,我想知道是否有人能帮我解决这个小问题 stack.hC 宏语法引起的错误,c,macros,C,Macros,我看到了下面的代码,其中一小部分没有意义,因为这超出了我目前的知识范围,我想知道是否有人能帮我解决这个小问题 stack.h #ifndef _STACK_H #define _STACK_H #include "lis1.h" typedef List Stack ; #define stack_init list_init #define stack_destroy list_destroy #define stack_size(stack) (stack)->size #def
#ifndef _STACK_H
#define _STACK_H
#include "lis1.h"
typedef List Stack ;
#define stack_init list_init
#define stack_destroy list_destroy
#define stack_size(stack) (stack)->size
#define stack_is_empty(stack) ((stack)->size==0)?1:0
int stack_push(Stack*stack,void*data);
int stack_pop(Stack*stack,void**data);
#endif
请注意#define stack_是空的(stack)((stack)->size==0)?1:0
在编写以下程序时
#include<stdio.h>
#include"stack.h"
static char ams[5] = { 'h', 'e', 'l', 'l', 'o' };
void* data;
Stack stack;
char*ss;
void debug(int a)
{
printf(" debug %d \n", a);
}
int main()
{
stack_init(&stack, NULL);
debug(1);
int i;
for (i = 0; i < 5; i++)
{
stack_push(&stack, (void*) (&ams[i]));
};
debug(2);
while (printf("checker\n") && stack_is_empty(&stack) != 1)
{
printf("->");
printf("[%d ", stack_size(&stack));
stack_pop(&stack, &data);
printf("%c]", *((char*) data));
printf("--\n");
};
return 0;
}
但是如果我改变#define stack#u是空的(stack)((stack)->size==0)?1:0
若要定义堆栈为空(堆栈)((堆栈)->大小==0)?1:0),则不存在seg故障
我的查询
我的问题是,为什么程序在前一种情况下工作得很好,直到条件输出一个“1”……我似乎理解了为什么后者在宏替换之后工作。
printf("checker\n")&&stack_is_empty(&stack)!=1
变成
printf("checker\n")&&((&stack)->size==0)?1:0!=1
由于三元运算符?:
的优先级相当低,因此相当于:
(printf("checker\n") && ((&stack)->size==0)) ? 1: (0 != 1)
请注意,printf(“checker\n”)
始终返回一个真值(因为它返回打印的字符数),因此由于存在快捷电路,因此不会计算check(&stack)->size==0)
建议:在宏定义中始终使用足够的括号。在宏替换之后
printf("checker\n")&&stack_is_empty(&stack)!=1
变成
printf("checker\n")&&((&stack)->size==0)?1:0!=1
由于三元运算符?:
的优先级相当低,因此相当于:
(printf("checker\n") && ((&stack)->size==0)) ? 1: (0 != 1)
请注意,printf(“checker\n”)
始终返回一个真值(因为它返回打印的字符数),因此由于存在快捷电路,因此不会计算check(&stack)->size==0)
建议:在宏定义中始终使用足够的括号。在C语言中,宏只是被文本替换,而不管它是否产生了您可能期望的表达式 如果没有括号,则
while
循环条件扩展为:
printf("checker\n")&&((&stack)->size==0)?1:0!=1
这被解释为:
(printf("checker\n") && ((&stack)->size==0)) ? 1 : (0 != 1)
因此,printf
成为这个三元表达式的条件的一部分,但这不会引起问题,它返回打印的字节数,只要它不是零,就会被解释为真。然后,根据实际情况,对检查堆栈大小的部件执行and。如果堆栈大小等于零,则返回1或true。如果堆栈大小不等于零,则返回(0!=1)
的结果,该结果始终为真。因此,这个条件总是返回一个真值,while循环继续运行,即使在堆栈上的项用完之后也是如此
添加括号时,会按预期进行解释:
printf("checker\n") && ((((&stack)->size==0)) ? 1 : 0) != 1)
编写扩展为表达式的宏时,应始终在结果周围加上一对括号,以确保将其解释为单个表达式,而不是可能导致表达式的解释与预期不同的运算符优先级规则
我应该注意到,这一发言中有许多重复之处。您正在检查布尔表达式的值,(&stack)->size==0
,以查看它是否为真,如果为真,则返回1,如果不是,则返回0。但是=
已经返回了一个1,如果它是真的,那么返回了一个0;不需要三元运算符。然后使用!=1
查看它是否为假。但是如何从布尔表达式中得到false呢?只需使用not运算符,代码>。您可以跳过三元运算符和!=1
比较:
#define stack_is_empty(stack) ((stack)->size==0)
while (!stack_is_empty(&stack)) {
// ...
}
在C语言中,宏只是被文本替换,而不管它是否产生了您可能期望的表达式
如果没有括号,则while
循环条件扩展为:
printf("checker\n")&&((&stack)->size==0)?1:0!=1
这被解释为:
(printf("checker\n") && ((&stack)->size==0)) ? 1 : (0 != 1)
因此,printf
成为这个三元表达式的条件的一部分,但这不会引起问题,它返回打印的字节数,只要它不是零,就会被解释为真。然后,根据实际情况,对检查堆栈大小的部件执行and。如果堆栈大小等于零,则返回1或true。如果堆栈大小不等于零,则返回(0!=1)
的结果,该结果始终为真。因此,这个条件总是返回一个真值,while循环继续运行,即使在堆栈上的项用完之后也是如此
添加括号时,会按预期进行解释:
printf("checker\n") && ((((&stack)->size==0)) ? 1 : 0) != 1)
编写扩展为表达式的宏时,应始终在结果周围加上一对括号,以确保将其解释为单个表达式,而不是可能导致表达式的解释与预期不同的运算符优先级规则
我应该注意到,这一发言中有许多重复之处。您正在检查布尔表达式的值,(&stack)->size==0
,以查看它是否为真,如果为真,则返回1,如果不是,则返回0。但是=
已经返回了一个1,如果它是真的,那么返回了一个0;不需要三元运算符。然后使用!=1
查看它是否为假。但是如何从布尔表达式中得到false呢?只需使用not运算符,代码>。您可以跳过三元运算符和!=1
比较:
#define stack_is_empty(stack) ((stack)->size==0)
while (!stack_is_empty(&stack)) {
// ...
}
请记住,C宏只是文本替换,而不是表达式求值
如果使用本影键控堆栈为空,则条件变为:
While (printf("checker\n") && ((&stack)->size)==0)?1:0!=1) {
While (printf("checker\n") && ((&stack)->size)==0)?1: (0!=1) ) {
问题是运算符具有高优先级,因此它实际上成为:
While (printf("checker\n") && ((&stack)->size)==0)?1:0!=1) {
While (printf("checker\n") && ((&stack)->size)==0)?1: (0!=1) ) {
从0开始1,while循环将继续超出堆栈的大小。请记住,C宏只是文本替换,而不是表达式求值
如果使用本影键控堆栈为空,则条件变为:
While (printf("checker\n") && ((&stack)->size)==0)?1:0!=1) {
While (printf("checker\n") && ((&stack)->size)==0)?1: (0!=1) ) {
问题是运算符具有高优先级,因此它实际上成为:
While (printf("checker\n") && ((&stack)->size)==0)?1:0!=1) {
While (printf("checker\n") && ((&stack)->size)==0)?1: (0!=1) ) {
从0开始1,while循环将继续超出堆栈的大小