Conteúdo do Curso
C Preprocessing
C Preprocessing
Advanced Usage of Symbolic Constant
Let's consider practical examples of using macro substitutions.
Multi-Line Macro
The \
(backslash) character in macros is used to continue the macro definition to the next line.
main
#include <stdio.h> #define PRINT_SUM(a, b) \ int sum = (a) + (b); \ printf("Sum: %d\n", sum); int main() { PRINT_SUM(3, 5); // Call a macro that prints "Sum: 8" return 0; }
Code duplication
This code uses the #define macro to shorten and avoid duplication of the same fields in two structures (struct Product
and struct Customer
)
main
#include <stdio.h> #define COMMON_FIELDS \ int id; \ char name[50]; \ float price; // Declare the Product structure struct Product { COMMON_FIELDS // Using the macro char category[30]; }; // Declare the Customer structure struct Customer { COMMON_FIELDS // Using the macro char email[50]; char address[100]; }; int main() { struct Product p1 = {1, "Laptop", 999.99, "Electronics"}; struct Customer c1 = {2, "Alice", 0.0, "alice@example.com", "123 Main St"}; printf("Product: %s,\n Category: %s,\n Price: %.2f\n", p1.name, p1.category, p1.price); printf("Customer: %s,\n Email: %s,\n Address: %s\n", c1.name, c1.email, c1.address); return 0; }
Checking Logical Conditions
The macro automatically replaces the validation code without the need to write it manually and allows you to display useful information about the error.
main
#include <stdio.h> #define CHECK(condition) \ if (!(condition)) { \ printf("Error: %s not running!\n", #condition); \ } int main() { int x = 5; CHECK(x > 0); // Executes without error CHECK(x == 10); // Print an error message return 0; }
Logging
The LOG_LEVEL macro sets the logging level (LOG_WARNING). Only ERROR and WARNING level messages will be output, and INFO will be ignored.
main
#include <stdio.h> // Defining logging levels #define LOG_ERROR 1 // For critical errors #define LOG_WARNING 2 // For reporting potential problems #define LOG_INFO 3 // For general information about program execution #define LOG_LEVEL LOG_WARNING // Set the desired logging level void log_message(int level, const char *message) { if (level <= LOG_LEVEL) { // Condition for checking the logging level switch (level) { case LOG_ERROR: printf("ERROR: %s\n", message); break; case LOG_WARNING: printf("WARNING: %s\n", message); break; case LOG_INFO: printf("INFO: %s\n", message); break; default: break; } } } int main() { log_message(LOG_ERROR, "This is an error message"); log_message(LOG_WARNING, "This is a warning message"); log_message(LOG_INFO, "This is an info message"); return 0; }
Swipe to start coding
Add a new logging level.
- Set the logging level for
LOG_DEBUG
; - Set the desired logging level;
- Set a condition that checks whether a message should be output for a specific logging level;
- Specify the message text that will be displayed if the condition is not met.
Solução
Obrigado pelo seu feedback!
Advanced Usage of Symbolic Constant
Let's consider practical examples of using macro substitutions.
Multi-Line Macro
The \
(backslash) character in macros is used to continue the macro definition to the next line.
main
#include <stdio.h> #define PRINT_SUM(a, b) \ int sum = (a) + (b); \ printf("Sum: %d\n", sum); int main() { PRINT_SUM(3, 5); // Call a macro that prints "Sum: 8" return 0; }
Code duplication
This code uses the #define macro to shorten and avoid duplication of the same fields in two structures (struct Product
and struct Customer
)
main
#include <stdio.h> #define COMMON_FIELDS \ int id; \ char name[50]; \ float price; // Declare the Product structure struct Product { COMMON_FIELDS // Using the macro char category[30]; }; // Declare the Customer structure struct Customer { COMMON_FIELDS // Using the macro char email[50]; char address[100]; }; int main() { struct Product p1 = {1, "Laptop", 999.99, "Electronics"}; struct Customer c1 = {2, "Alice", 0.0, "alice@example.com", "123 Main St"}; printf("Product: %s,\n Category: %s,\n Price: %.2f\n", p1.name, p1.category, p1.price); printf("Customer: %s,\n Email: %s,\n Address: %s\n", c1.name, c1.email, c1.address); return 0; }
Checking Logical Conditions
The macro automatically replaces the validation code without the need to write it manually and allows you to display useful information about the error.
main
#include <stdio.h> #define CHECK(condition) \ if (!(condition)) { \ printf("Error: %s not running!\n", #condition); \ } int main() { int x = 5; CHECK(x > 0); // Executes without error CHECK(x == 10); // Print an error message return 0; }
Logging
The LOG_LEVEL macro sets the logging level (LOG_WARNING). Only ERROR and WARNING level messages will be output, and INFO will be ignored.
main
#include <stdio.h> // Defining logging levels #define LOG_ERROR 1 // For critical errors #define LOG_WARNING 2 // For reporting potential problems #define LOG_INFO 3 // For general information about program execution #define LOG_LEVEL LOG_WARNING // Set the desired logging level void log_message(int level, const char *message) { if (level <= LOG_LEVEL) { // Condition for checking the logging level switch (level) { case LOG_ERROR: printf("ERROR: %s\n", message); break; case LOG_WARNING: printf("WARNING: %s\n", message); break; case LOG_INFO: printf("INFO: %s\n", message); break; default: break; } } } int main() { log_message(LOG_ERROR, "This is an error message"); log_message(LOG_WARNING, "This is a warning message"); log_message(LOG_INFO, "This is an info message"); return 0; }
Swipe to start coding
Add a new logging level.
- Set the logging level for
LOG_DEBUG
; - Set the desired logging level;
- Set a condition that checks whether a message should be output for a specific logging level;
- Specify the message text that will be displayed if the condition is not met.
Solução
Obrigado pelo seu feedback!