Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Self-cultivation of embedded C language 03: macro Construction weapon-sentence expression

2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

3.1 basic review: expressions, statements, and code blocks

Expression.

Expressions and statements are the basic concepts in C language. What is an expression? An expression is an expression made up of a series of operators and operands. Operators can be various arithmetic operators, logical operators, assignment operators, comparison operators, etc., specified in the C language standard. The Operand can be either a constant or a variable. An expression can also have no operator, and a single constant or even a string is an expression. The following character sequences are expressions:

2 + 32i = 2 + 3i = iTunes + + 3 "wit"

Expressions are generally used to calculate data or to implement an algorithm for a function. Expressions have two basic properties: value and type. As in the expression 2x3 above, its value is 5. Depending on the operator, expressions can be divided into several types, such as:

Relational expressions, logical expressions, conditional expressions, assignment expressions, arithmetic expressions.

Statement

Statement is the basic unit of a program, which is generally in the following form:

Expression; I = 2 + 3

Adding one at the end of the expression forms a basic statement. When compiling and parsing a program, the compiler judges the closing tag of a statement not by the physical line, but by the semicolon. For example, I = 2 + 3; if you write this sentence in the following form, you can also compile it:

I = 2 + 3

Code block

Different statements, enclosed in curly braces {}, form a block of code. The C language allows a variable to be defined in a code block, and the scope of this variable is limited to this code block, because the compiler manages the scope of the variable according to {}. Such as the following procedure:

Int main (void) {int% d\ n ", I); {int% d\ n", I); {int% d\ n ", I);} printf (" I% d\ n ", I); return 0;} run result is: i=3i=4i=33.2 statement expression

Definition of statement expression

GNU C extends the C standard to allow embedded statements in an expression, allowing local variables, for loops, and goto jump statements to be used inside the expression. Such an expression is called a statement expression. The format of the statement expression is as follows:

({expression 1; expression 2; expression 3;})

The statement expression is enclosed in parentheses (). Inside a pair of curly braces {} is a code block, which allows various statements to be embedded. The format of the statement can be "expression;" which is a general format, or it can be a loop, jump, and so on.

Like general expressions, statement expressions have their own values. The value of the statement expression is the value of the last expression in the embedded statement. Let's give an example of using statement expressions to evaluate.

Int main (void) {int sum = 0; sum = ({int s = 0; for (int I = 0; I)

< 10; i++) s = s + i; s; }); printf("sum = %d\n",sum); return 0;} 在上面的程序中,通过语句表达式实现了从1到10的累加求和,因为语句表达式的值等于最后一个表达式的值,所以在 for 循环的后面,我们要添加一个 s; 语句表示整个语句表达式的值。如果不加这一句,你会发现 sum=0。或者你将这一行语句改为100; 你会发现最后 sum 的值就变成了100,这是因为语句表达式的值总等于最后一个表达式的值。 语句表达式内使用 goto 跳转 在上面的程序中,我们在语句表达式内定义了局部变量,使用了 for 循环语句。在语句表达式内,我们同样也可以使用 goto 进行跳转。 int main(void){ int sum = 0; sum = ({ int s = 0; for( int i = 0; i < 10; i++) s = s + i; goto here; s; }); printf("sum = %d\n",sum);here: printf("here:\n"); printf("sum = %d\n",sum); return 0;}3.3 在宏定义中使用语句表达式 语句表达式的亮点在于定义复杂功能的宏。使用语句表达式来定义宏,不仅可以实现复杂的功能,而且还能避免宏定义带来的歧义和漏洞。下面就以一个宏定义例子,让我们来见识见识语句表达式在宏定义中的强悍杀伤力! 假如你此刻正在面试,面试职位是:Linux C 语言开发工程师。面试官给你出了一道题: 请定义一个宏,求两个数的最大值。 别看这么简单的一个考题,面试官就能根据你写出的宏,来判断你的 C 语言功底,来决定给不给你 Offer。 合格 对于学过 C 语言的同学,写出这个宏基本上不是什么难事,使用条件运算符就能完成: #define MAX(x,y) x >

Y? X: y

This is the most basic C language grammar, if you can't even write this, it will be awkward. In order to ease the embarrassment, the interviewer will usually say to you: young man, you are very good, go back and wait for the news, if there is any news, we will let you know! At this time, you should understand: you don't have to wait any longer, read this article quickly, and then go home. This macro can be written, do not think you are very good X, because it can only show that you have the foundation of C language, but there is still a lot of room for improvement. For example, let's write a program to verify that the macros we defined are correct:

# define MAX (XBI y) x > y? X: yint main (void) {printf ("max=%d", MAX (1 Magazine 2)); printf ("max=%d", MAX (2 Magazine 1)); printf ("max=%d", MAX (2 Magazine 2); printf ("max=%d", MAX); return 0;}

As for the test program, we are sure to test all possible situations. No, test line 4, when the argument to the macro is an expression, we find that the actual run result is max=0, which is not the same as our expected result max=1. This is because, when the macro unfolds, it looks like this:

Printf ("max=%d", 1 / 2 > 1 / 2 / 1 / 2)

Because the priority of the comparison operator > is 6, which is greater than! = (priority 7), the order of the expanded expression is changed, and the result is not what we expected. To avoid this expansion error, we can add a parenthesis () to the parameter of the macro to prevent the operation order of the expression from changing after expansion. Such a macro can be considered a qualified macro:

# define MAX (XBI y) (x) > (y)? (X): (y)

Medium

The above macros can only be considered qualified, but there are still loopholes. For example, we use the following code to test:

# define MAX (XBI y) (x) > (y)? (X): (y) int main (void) {printf ("max=%d", 3 + MAX (1Magne2)); return 0;}

In the program, we print the value of the expression 3 + MAX (1, 2). The expected result should be 5, but the actual running result is 1. When we unfolded, we found that there was also a problem:

3 + (1) > (2) (1): (2)

Because the operator + takes precedence over the comparison operator >, this expression becomes 4 > 2 equal to 1, and it's not surprising that the final result is 1. At this point, we should continue to modify the macro:

# define MAX (XBI y) ((x) > (y)? (X): (y))

Wrap the macro definition in parentheses to avoid breaking the order of the entire expression when it contains both the macro definition and other high-priority operators. If you can write to this step, it means that you are better than the previous classmate who passed the interview. The former classmate has gone back to wait for the news, and we will go on to the next round of the interview.

Good

Although the above macro solves the problem caused by operator precedence, it still has some loopholes. For example, we use the following test program to test the macros we define:

# define MAX (XBI y) ((x) > (y)? (X): (y) int main (void) {int I = 2; int j = 6; printf ("max=%d", MAX); return 0;}

In the program, we define two variables I and j, then compare the size of the two variables, and do self-increment operation. The actual running result is found to be max = 7 instead of the expected result max = 6. This is because the variables I and j do two self-increment operations after the macro is expanded, resulting in printing out a value of 7.

In such a situation, what should we do? At this point, the statement expression should be on the stage. We can use the statement expression to define this macro, define two temporary variables in the statement expression, temporarily store the values of I and j, and then compare them, so as to avoid the problems of self-increment and self-subtraction.

# define MAX (int y) ({\ int _ x = x;\ int _ y = y;\ _ x > _ y? _ x: _ y;\}) int main (void) {int I = 2; int j = 6; printf ("max=%d", MAX); return 0;}

In the statement expression, we define two local variables _ x and _ y to store the values of macro parameters x and y, and then use _ x and _ y to compare the size, so as to avoid the problem of two self-increment operations caused by I and j.

If you can hold on to this level and write such a macro with your own BGM, the interviewer may already have the will to give you Offer. But at this moment, don't be proud! In order to completely allay the interviewer's psychological concerns, we need to continue to optimize this macro.

Excellent

In the above macro, the two temporary variable data types we defined are of type int, and only two integers can be compared. Then for other types of data, you need to redefine a macro, which is too troublesome! We can continue to modify based on the above macro so that it can support any type of data comparison size:

# define MAX (type,x,y) ({\ type _ x = x;\ type _ y = y;\ _ x > _ y? _ x: _ y;\}) int main (void) {int I = 2; int j = 6; printf ("max=%d\ n", MAX (int,i++,j++)); printf ("max=%f\ n", MAX (float,3.14,3.15)) Return 0;}

In this macro, we add a parameter: type, which specifies the type of temporary variables _ x and _ y. In this way, when we compare the size of two numbers, we can compare any type of data as long as we pass the type of 2 data as parameters to the macro. If you can write such a macro in the interview, the interviewer will be very happy. He will usually say to you: wait a minute, HR will talk to you about the salary later.

Can it be better?

If you want to get a higher salary and a better salary, you should not be proud at this time. You should wave your hand: wait a minute, I can be better!

In the macro definition above, we have added a type type parameter to be compatible with different data types, which should be omitted for the sake of salary at this point. How do you do that? It's OK to use typeof. Typeof is a new keyword added by GNU C to get the data type. We don't need to pass parameters in, let typeof get it directly!

# define max (x, y) ({\ typeof (x) _ x = (x);\ typeof (y) _ y = (y);\ (void) (& _ x = = & _ y);\ _ x > _ y? _ x: _ y;})

In this macro definition, the typeof keyword is used to get the two parameter types of the macro. Practical information in (void) (& x = = & y); this sentence, it is a genius design! First, it is used to give the user a warning, for different types of pointer comparison, the compiler will give a warning that the two data types are different; second, when the two values are compared, the result of the comparison is not used, some compilers may give a warning, add a (void), you can eliminate this warning!

At the moment, the interviewer will probably take a breath when he sees your macro: boy, it's really awesome, this guy is better than me! You wait. HR will come and talk to you about your salary later!

Congratulations, you got the offer!

3.4 the use of statement expressions in the Linux kernel

Statement expressions, as an extension of the C standard by GNU C, are widely used in the kernel, especially in the macro definition of the kernel. Using statement expressions to define macros can not only achieve complex functions, but also avoid some ambiguities and loopholes caused by macro definitions. For example, in the Linux kernel, the macro definitions of max_t and min_t use statement expressions:

# define min_t (type, x, y) ({\ type _ min1 = (x);\ type _ min2 = (y);\ _ _ min1

< __min2 ? __min1 : __min2; })#define max_t(type, x, y) ({ \ type __max1 = (x); \ type __max2 = (y); \ __max1 >

_ _ max2? _ _ max1: _ _ max2;})

In addition, in the Linux kernel and GNU open source software, you will find that there are a large number of macro definitions that use statement expressions. Through the study of this tutorial, I believe that if you encounter this kind of macro defined by sentence expression in the future, you will know what is going on. There are hills in your heart, and you don't have to panic any more.

This tutorial is adapted from the C language embedded Linux Advanced programming Video tutorial No. 05, the electronic version of the book can join the QQ group: 475504428 download, more embedded video tutorials, you can follow:

Official account of Wechat: Otaku tribe (armlinuxfun)

51CTO College-Mr. Wang Litao: http://edu.51cto.com/sd/d344f

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report