Detailed explanation of C language operators (on)

foreword

In the C language, the C standard provides a wealth of operators, which are used to operate and calculate data, such as mathematical calculations, comparisons, and logical operations. Operators are a very important part of programming languages. They can make programs more concise and efficient, and can also enhance the readability and maintainability of code. This article will systematically introduce C language operators in detail, hoping to help readers fully understand C language operators!

1. Arithmetic operators

Arithmetic operators are divided into the following five types. Although they are simple, there are still some details that need attention.

+)、(-)、(*)、(/)、(%

  • In addition to the % (modulus) operator, several other operators work on integers and floating-point numbers.
  • For the / operator, if both operands are integers, integer division is performed. Instead, floating-point division is performed whenever there is a single floating-point number.
  • Both operands of the % operator must be integers. Returns the remainder after division.

2. Shift operator

In C language, shift operators are divided into the following two types

  • << left shift operator
  • >> right shift operator

Relevant knowledge supplement:

#include <stdio.h>
int main()
{
    
    
	int a = 15;
	//00000000000000000000000000001111 - 原码
	//00000000000000000000000000001111 - 反码
	//00000000000000000000000000001111 - 补码

	int b = -15;
	//10000000000000000000000000001111 - 原码
	//11111111111111111111111111110000 - 反码
	//11111111111111111111111111110001 - 补码
	return 0;
}

Tips:

  • The operands of shift operators can only be integers.
  • Computers can process binary information. The binary representation of integers is divided into three types: original code, inverse code, and complement code.
  • The original code, inverse code, and complement code of positive integers are the same. The inverse code of the negative integer is that the sign bit of the original code remains unchanged, and the complement code is obtained by adding 1 to the inverse code of other non-bitwise inverse codes.

2.1 Left shift operator ( << )

Shift rules:

Discard on the left, add 0 to the right

example:

#include <stdio.h>
int main()
{
    
    
	int a = 15;
	//00000000000000000000000000001111 - (a)补码

	int b = a << 1;
	//对a的补码右移一位得到b的补码,左边抛弃,右边补0
	//00000000000000000000000000011110 - (b)补码
	//00000000000000000000000000011110 - (b)反码
	//00000000000000000000000000011110 - (b)原码
	
	printf("b=%d\n", b); //b得值为:30
	return 0;
}

2.2 Right Shift Operator ( >> )

Shift rules:

In C language, there are two types of right shift operations:

  1. Logical right shift: pad with 0 on the left and discard on the right.
    2. Arithmetic right shift: the left side is filled with the sign bit of the original value, and the right side is discarded.

For the above two operation methods, the C language does not clearly stipulate whether it is an arithmetic right shift or a logical right shift. But the general compiler uses arithmetic right shift.
example:

int main()
{
    
    
	int a = -15;
	//10000000000000000000000000001111 - 原码
	//11111111111111111111111111110000 - 反码
	//11111111111111111111111111110001 - 补码

	int b = a >> 1;
	//左边用原该值的符号位填充,右边丢弃
	//11111111111111111111111111111000 - 补码
	//11111111111111111111111111110111 - 反码
	//10000000000000000000000000001000 - 原码
	
	printf("b=%d\n", b); //b的值为:-8
	return 0;
}

Warning:
For shift operators, do not shift negative digits, this behavior is undefined by the C standard.

int num=10;
num>>-1; //error

3. Bitwise operators

In C language, there are three types of bit operators: & (bitwise and), | (bitwise or), ^ (bitwise exclusive or).
Tips: The operands of bit operators must be integers, and they also operate on binary bits.

3.1 Bitwise AND ( & )

& — The binary bit corresponding to the complement code is 0 if it is 0, and it is 1 if both are 1 at the same time.

example:

int main()
{
    
    
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a & b;
	//&补码对应的二进制位有0则为0,两个同时为1才是1.
	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//00000000000000000000000000000011 - 补码(c)

	printf("c=%d\n", c); //c的值为:3
	return 0;
}

3.2 Bitwise OR ( | )

| — If the binary bit corresponding to the complement code has 1, it is 1, and if two of them are 0 at the same time, it is 0.

example:

int main()
{
    
    
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a | b;
	//&补码对应的二进制位有1则w为1,两个同时为0才是0.
	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//11111111111111111111111111111011 - 补码(c)

	//11111111111111111111111111111010 - 反码(c)
	//10000000000000000000000000000101 - 原码(c)

	printf("c=%d\n", c);//c的值为:-5
	return 0;
}

3.4 Bitwise XOR ( ^ )

|^— If the binary bits corresponding to the complement code are not the same, it is 1, and if two of them are the same, it is 0.

int main()
{
    
    
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a ^ b;
	//^ 补码对应的二进制位不相同则为1,两个同时为1或0时才是0.

	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//11111111111111111111111111111000 - 补码(c)

	//11111111111111111111111111110111 - 反码(c)
	//10000000000000000000000000001000 - 原码(c)

	printf("c=%d\n", c);//c的值为:-8
	return 0;
}

3.5 A perverted interview question

A temporary variable (the third variable) cannot be created to exchange two numbers.

int main()
{
    
    
	int a = 10;
	int b = 20;
	//交换,按位异或是支持交换律的
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}
  • Bitwise XOR supports the commutative law.

4. Relational Operators

insert image description here
These relational operators are relatively simple and there is nothing to introduce.

5. Unary operators

Introduction to unary operators:

insert image description here

5.1 Unary operator ( ! )

( ! ) Logical inverse operation, as the name implies, is to turn true into false and false into true.

int main()
{
    
    
	int flag = 0;//下面两种判断flag为0就执行语句的方法,效果一样
	//方法1:
	if (flag == 0)
	{
    
    
		//语句;
	}

	//方法2:flag为0,则为假。!flag则为真,执行语句
	if (!flag)
	{
    
    
		//语句;
	}
	return 0;
}

5.2 Unary operator ( ~ )

The unary operator ( ~ ) is to invert all the two's complement binary bits. (including the sign bit)

example:

int main()
{
    
    
	int a = 0;
	//00000000000000000000000000000000 - 补码

	int b = ~a;
	//~a--对a的补码全部取反
	//11111111111111111111111111111111 - 补码
	//11111111111111111111111111111110 - 补码
	//10000000000000000000000000000001 - 原码

	printf("%d\n", b); //b的值位:-1
	return 0;
}

5.3 Unary operators ( &, * )

The unary operators ( &, * ) all work on pointers.

int main()
{
    
    
	int a = 0;
	//pa是指针变量
	int* pa = &a; //&—取地址操作符—取出a的地址
	
	//解引用操作符(间接访问操作符)—通过pa中存放的地址,找到指向的空间(内容)
	*pa = 20;
	return 0;
}

5.4 Unary operators ( ++, – )

The unary unary operator ++ ( - - ) is divided into pre ++ ( - - ) and post ++ ( ) .
Pre ++ ( ): first ++ (- -), in use. Postfix ++ ( - ): Use first, after ++(- -).

Example 1:

int main()
{
    
    

	int a = 2;
	int b = --a; //前置--,先--,在使用
	//a=a-1,b=a
	printf("a=%d b=%d\n", a, b);//a,b的值都为:1	
	return 0;
}

Example 2:

int main()
{
    
    
	int a = 2;
	int b = a--; //后置--,先使用,在--
	//b=a,a=a-1
	printf("a=%d b=%d\n", a, b);//a的值为1,b的值为2
	return 0;
}

The same is true for pre ++ and post ++.

5.5 The unary operator ( sizeof ) and arrays

The unary operator ( sizrof ) is used to calculate the type length of an operand. (unit byte)

#include <stdio.h>
void test1(int arr[])
{
    
    
	printf("%d\n", sizeof(arr));
}

void test2(char ch[])
{
    
    
	printf("%d\n", sizeof(ch));
}
int main()
{
    
    
	int arr[10] = {
    
     0 };
	char ch[10] = {
    
     0 };
	printf("%d\n", sizeof(arr));//10X4
	printf("%d\n", sizeof(ch)); //10X1
	test1(arr);
	test2(ch);
	return 0;
}

Running results (in x64 environment):
insert image description here
The first two results above are beyond doubt, but why are the last two 8bytes?
The functions test1() and test2() are called above, and the pointers are passed. In C language, on a 64-bit machine (x64), the pointer size is 8byte; on a 32-bit machine (x86), the pointer size is 4byte.

6. Logical operators

In C language, logical operators are divided into the following two types:

&& — logical AND
|| — logical OR

To put it simply: logical and ( && ) is true when both are in the city at the same time, otherwise it is false; logical or ( || ) is true as long as one of them is true, otherwise it is false.
Tips:

  • The && operator, the left side is false, and the right side is not calculated.
  • || operator, the left side is true, and the right side does not need to be calculated.

Example 1:

#include <stdio.h>
int main()
{
    
    
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//后置++,先使用a,后再执行++
	//&&操作符,左边为假,右边就不计算了
	//a先使用,为0,则为假。所以&&后面所有运算都不执行
	i = a++ && ++b && d++;
	//结果:a=1 b=2 c=3 d=4
	printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);
	return 0;
}

example:

#include <stdio.h>
int main()
{
    
    
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//||操作符,左边为真,右边就不用计算了。
	//使用b时,b先++后使用,别的值为3,非0为真。所以后面所有运算都不进行
	i = a++ || ++b || d++;
	//结果:a=1 b=3 c=3 d=4
	printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);
	return 0;
}

7. Relational Operators

In the C language, the relational operators are as follows: if the expression exp1 is true, then the expression exp2 is executed, otherwise the expression exp3 is executed.

exp1 ? exp2 : exp3

example:

int main()
{
    
    
	int a = 0;
	int b = 0//a为0小于5,执行表达式xep3。所以b=-3
	b = (a > 5) ? 3 : -3;
	return 0;
}

8. Comma expressions

In C language, a comma expression is: multiple expressions separated by commas.

exp1, exp2, exp3, …expN

example:

int main()
{
    
    
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式
	printf("c=%d\n", c);//结果为:c=13
	return 0;
}

Then in the above code, why does the value of c end up being 13?

  • Comma expressions are evaluated from left to right. The result of the entire expression is the result of the last expression.

example:

int d=1;
if(a=a+1,c=a/2,d>0)//d大于0,结果为真,执行if后的语句块
{
    
    }

9. Subscript references, function calls, and structure members

9.1 [ ] subscript reference operator

In C language, the operand of the subscript reference is: an array name + an index value ( the two operands satisfy the commutative law)

example:

int main()
{
    
    
	int arr[10] = {
    
     1,2,3,4,5,6,7,8,9,10 };//数组的起始是有下标的,下标从0开始
	//			    0 1 2 3 4 5 6 7 8 8 9
	printf("%d\n", arr[2]);// [] 下标引用操作符,arr和2是两个操作数
	printf("%d\n", 2[arr]);
	return 0;
}
  • Although 2[arr] in the above code looks strange, it is established and is equivalent to arr[2]. [ ], like +, are operands, regardless of the order of the two operands.

9.2 ( ) function call operator

The ( ) function call operator can accept one or more operands: the first operand is the function name, and the remaining operands are the parameters passed to the function.

example:

#include <stdio.h>
#include <string.h>
int Add(int x, int y)
{
    
    
	return x + y;
}

int main()
{
    
    
	int len = strlen("abc");//( )函数调用操作符
	//()的操作数是:strlrn 和 "abc
	printf("%d\n", len);

	int c = Add(3, 5);//( ) 函数调用操作符
	//()的操作数是:Add 和3 5
	//对于函数调用操作符来说,至少有一个操作数

	printf("%d\n", c);
	return 0;
}

9.3 Accessing members of a structure

In C language, there are two ways to access the members of a structure:

. —Structure.Member Name- > —Structure- > Member Name _ _

Example 1:

#include <stdio.h>
//定义一个struct Book类型
struct Book
{
    
    
	char name[30];
	char author[20];
	float price;
};

int main()
{
    
    
	struct Book b= {
    
     "C primer Plus","Stephen Prate",47.8f };//创建一个变量b
	//结构体.成员名,答应相关信息
	printf("%s %s %.1f\n", b.name, b.author, b.price);
	return 0;
}

Example 2:

struct Book
{
    
    
	char name[30];
	char author[20];
	float price;
};
//定义过程
void print(struct Book* b)
{
    
    
	//结构指针->成员名,访问成员
	printf("%s %s %.1f\n", b->name, b->author, b->price);
}

int main()
{
    
    
	struct Book b= {
    
     "C primer Plus","Stephen Prate",47.8f };//创建一个变量b
	//封装print()函数,打印信息
	print(&b);
	return 0;
}

10. Ending

This concludes this article! In the Detailed Explanation of C Language Operators (Part 1), all the operations in C language have been introduced in detail and systematically. Next, in the Detailed Explanation of C Language Operators (Part 2), we will introduce in detail the things and operations that the compiler does behind executing these codes. Symbol precedence, associativity, and order of evaluation!
It is not easy to create, if it is helpful to you, remember to like and pay attention! Thank you for your support, and readers are welcome to express their opinions!
Detailed explanation of C language operators (below)

Guess you like

Origin blog.csdn.net/Zhenyu_Coder/article/details/130695242