2016-03-18 4 views
0

Я реализую подробный режим. Вот что я пытаюсь сделать: определение глобальной переменной VERBOSE (в verbose.h) таким образом, что файлы, требующие подробного, должны включать этот файл. Например:Реализация подробных в C

verbose.h:

void setVerbose(int test); 

verbose.c:

#include "verbose.h" 

// define VERBOSE if called 
void setVerbose(int test) { 
    if (test) { 
     #ifndef VERBOSE 
     #define VERBOSE 
     #endif 
    } 
} 

point.h:

typedef struct Point Point; 
struct Point { 
    int x, y; 
}; 

void printPoint(Point *point); 

point.c:

#include "point.h" 
#include "verbose.h" 

void printPoint(Point *point) { 
    #ifdef VERBOSE 
     printf("My abscissa is %d\n", point->x); 
     printf("My ordinate is %d\n", point->y); 
    #endif 

    printf("[x,y] = [%d, %d]\n", point->x, point->y); 
} 

И главное:

main.c:

#include "verbose.h" 
#include "point.h" 

int main(int argc, char *argv[]) { 
    if (argc >= 2 && !strcmp(argv[1], "-v")) 
     setVerbose(1); 

    Point *p = init_point(5,7); 
    printPoint(p); 

    return 0; 
} 

Исполняемый было произведено с:

$ gcc -o test main.c point.c verbose.c 

Выходы хотели являются:

$ ./test 
    [x,y] = [5, 7] 

$ ./test -v 
    My abscissa is 5 
    My ordinate is 7 
    [x,y] = [5, 7] 

Проблема в том, что кажется, что VERBOSE не определяется в point.c при вызове printPoint().

+2

Пожалуйста, перечитайте концепцию предварительной обработки , –

+4

'# define' является директивой ** препроцессора **. Помещение #define внутри оператора if бессмысленно. Это '# define' переводится до компиляции программы. –

+0

Другие упомянули проблему, поэтому я просто предлагаю вам использовать ** регистрационный класс ** вместо вашего текущего подхода. Это намного более гибко. Например, я написал один для Arduino некоторое время назад https://abrushforeachkeyboard.wordpress.com/2014/06/17/arduino-adding-a-logger-class-with-ac-style-print-of-messages/ –

ответ

0

Команды препроцессора решаются во время компиляции, а не время запуска, поэтому ваша система не будет работать. Вместо этого я бы рекомендовал использовать глобальный bool Verbose и предоставить функцию verbose() для печати (или нет).

verbose.h

#include <stdbool.h> 

int verbose(const char * restrict, ...); 
void setVerbose(bool); 

verbose.c

#include "verbose.h" 
#include <stdbool.h> 
#include <stdarg.h> 
#include <stdio.h> 

bool Verbose = false; 

void setVerbose(bool setting) { 
    Verbose = setting; 
} 

int verbose(const char * restrict format, ...) { 
    if(!Verbose) 
     return 0; 

    va_list args; 
    va_start(args, format); 
    int ret = vprintf(format, args); 
    va_end(args); 

    return ret; 
} 

main.c

#include "verbose.h" 
#include <stdbool.h> 

int main() { 
    verbose("Verbose is off\n"); 

    setVerbose(true); 

    verbose("Verbose is on\n"); 

    int foo = 42; 

    verbose("Number: %d\n", foo); 

    return 0; 
} 
+1

* Команды препроцессора решаются во время компиляции * - Это неверно. Прекомпромисс выйдет перед компилятором. –

+0

@EdHeal. Вы технически верны! ... и это не меняет ответ на один бит. Важно то, что это не происходит во время выполнения. 't выяснить, как объяснить предварительный процессор против компиляции против времени выполнения без лишнего усложнения ответа, может быть, вы можете в своем собственном ответе или редактировании? – Schwern

+1

Я подумаю об этом легко объяснять для плаката –