[C-Sprachgrundlage 8 - detaillierte Erklärung der Operatoren (1)]


Vorwort

Zu den Hauptinhalten von Operatoren gehören: die Einführung verschiedener Operatoren und die Auswertung von Ausdrücken.


1. Klassifizierung der Betreiber

  • Rechenzeichen
  • Schichtbetreiber
  • bitweiser Operator
  • Aufgabenverwalter
  • unärer Operator
  • Vergleichsoperator
  • logischer Operator
  • Bedingter Operator
  • Komma-Ausdruck
  • Tiefgestellte Verweise, Funktionsaufrufe und Strukturmitglieder

2. Arithmetische Operatoren

 +  -  *  /  %  (加法 减法 乘法 取余 取模)
int main()
{
    
    
	int a = 9 / 2;//4
	float b = 9 / 2;
	int c = 9.0 / 2;
	float d = 9.0 / 2;//4.5
	float e = (float)9.0 / 2;

	printf("%d\n", a);
	printf("%f\n", b);
	printf("%d\n", c);
	printf("%f\n", d);
	printf("%f\n", e);
	return 0;
}

Das laufende Ergebnis ist in der folgenden Abbildung dargestellt:
Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen
Bildbeschreibung hier einfügen
Anhand des Beispiels kann festgestellt werden, dass bei falscher Verwendung des Variablentyps auch das Ergebnis falsch ist

  • Neben dem %-Operator können mehrere andere Operatoren mit ganzen Zahlen und Gleitkommazahlen arbeiten
  • Für den /-Operator wird eine ganzzahlige Division durchgeführt, wenn beide Operanden ganze Zahlen sind. Und solange Gleitkommazahlen vorhanden sind, wird eine Gleitkommadivision durchgeführt.
  • Beide Operanden des %-Operators müssen ganze Zahlen sein. Gibt den Rest nach der Division zurück

3. Schichtoperator

Operanden von Shift-Operatoren können nur Ganzzahlen sein

<< 左移操作符
>> 右移操作符

3.1 Linksverschiebungsoperator

Verschieberegeln: links verwerfen, rechts 0 addieren

  • Integer ist vom Typ int, belegt 4 Bytes und hat eine 32-Bit-Darstellung. Das höchste Bit stellt das Vorzeichen dar, 0 ist positiv und 1 ist negativ
  • Ganze Zahlen werden im Zweierkomplement-Binärspeicher gespeichert, und der ursprüngliche Code, der inverse Code und der Komplementcode positiver Zahlen sind gleich
  • Der Ablauf von Operatoroperationen auf ganzen Zahlen:
  • (1) Wandeln Sie zuerst den ursprünglichen Code der ganzen Zahl in den inversen Code um
  • (2) Inverscode + 1 wird in Komplementcode umgewandelt
  • (3) Bearbeite schließlich das Komplement der ganzen Zahl
  • (4) Nachdem die Operation abgeschlossen ist, wandele den Komplementcode –1 nach der Operation in den Komplementcode um
  • (5) Wandeln Sie den inversen Code in den endgültigen ursprünglichen Code um
  • Die Funktion printf gibt den Originalcode der Ganzzahl aus

3.1.1 Beispiel 1 - Schieben Sie eine positive Zahl um 1 Bit nach links

Der Code lautet wie folgt (Beispiel):

int main()
{
    
    
	int a = 5;
	int b = a << 1;//操作的补码二进制位,a本身结果不变
	printf("%d\n", a);//打印5
	printf("%d\n", b);// -10
	return 0;
}

Bildbeschreibung hier einfügen

Die Ergebnisoperation ist in der folgenden Abbildung dargestellt, die mit dem Analyseergebnis übereinstimmt.Der Effekt der Linksverschiebung um 1 Bit entspricht der Multiplikation mit 2. In 51-Einzelchip-Mikrocomputern und STM32 wird das Operationsregister häufig verwendet.
Bildbeschreibung hier einfügen

3.1.2 Beispiel 2 - Verschiebe eine negative Zahl um 1 Bit nach links

int main()
{
    
    
	int a = -5;
	int b = a << 1;//<< >> 操作的二进制位
	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -10
	return 0;
}

Bildbeschreibung hier einfügen

Die Laufergebnisse sind in der Abbildung unten dargestellt und stimmen mit den Analyseergebnissen überein.
Bildbeschreibung hier einfügen

3.2 Rechtsverschiebungsoperator

Es gibt zwei Arten von Rechtsverschiebungsregeloperationen:

  • Logische Verschiebung: Links mit 0 auffüllen, rechts verwerfen

  • Arithmetische Verschiebung: Die linke Seite wird mit dem Vorzeichenbit des ursprünglichen Werts gefüllt, und die rechte Seite wird verworfen

3.2.1 Beispiel 1 - Verschiebe eine positive Zahl um 1 nach rechts

int main()
{
    
    
	int a = 5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

Der Prozess der Verschiebung nach rechts wird unten analysiert: der ursprüngliche Code, der inverse Code und der Komplementcode positiver Zahlen sind gleich

00000000 00000000 00000000 00000101 //5的二进制补码
//算术右移:左边用原该值的符号位1填充,右边丢弃1
00000000 00000000 00000000 00000010 //右移后的补码
//右移后的补码就是右移后的原码  2

Das Ergebnis ist unten dargestellt:
Bildbeschreibung hier einfügen

3.2.2 Beispiel 2 - Verschiebe eine negative Zahl um 1 nach rechts

int main()
{
    
    
	int a = -5;
	int b = a >> 1;//右移不一定是除2

	printf("%d\n", a);//打印-5
	printf("%d\n", b);// -3
	return 0;
}

Die folgende Analyse des Prozesses der Rechtsverschiebung:

10000000 00000000 00000000 00000101 //-5的二进制原码
11111111 11111111 11111111 11111010 //反码
11111111 11111111 11111111 11111011 //补码:反码+1
//算术右移:左边用原该值的符号位1填充,右边丢弃1
11111111 11111111 11111111 11111101 //右移后的补码
11111111 11111111 11111111 11111100 //反码:补码-1
10000000 00000000 00000000 00000011 //原码  -3

Das Ergebnis ist unten dargestellt:
Bildbeschreibung hier einfügen

3.3 Beschreibung des Schichtbetreibers

Vorsichtsmaßnahmen:

  • Der Rechtsverschiebungsoperator verwendet eine logische Verschiebung oder eine arithmetische Verschiebung, abhängig vom Computercompiler Meiner ist eine arithmetische Verschiebung, daher wird das Beispiel durch eine arithmetische Verschiebung analysiert, und der Analyseprozess der logischen Verschiebung ist derselbe.
  • Verschieben Sie bei Schiebeoperatoren keine negativen Bits, dies ist im Standard nicht definiert, zum Beispiel:
int num = 10;
num>>-1;//10右移-1位,这是错误的表达

4. Bitweise Operatoren

Bitoperatoren sind:

& //按位与     相同为1, 相异为0
| //按位或     有1为1, 全0为0
^ //按位异或    相同为0, 相异为1
//注:他们的操作数必须是整数
int main()
{
    
    
	int a = 3;
	int b = -5;
	int c = a & b;
	int d = a | b;
	int e = a ^ b;//异或
	//对应的二进制位:相同位0,相异为1
	printf("%d\n", c);// 打印3
	printf("%d\n", d);// -5
	printfan("%d\n", e);// -8	
	return 0;
}
00000000 00000000 00000000 00000011   3的补码
11111111 11111111 11111111 11111011   -5的补码
//按位与:  相同为1, 相异为0
00000000 00000000 00000000 00000011    3的补码,原码表示3
//按位或:   有1为1, 全0为0
11111111 11111111 11111111 11111011   -5的补码,原码表示-5
//按位异或: 相同为0, 相异为1
11111111 11111111 11111111 11111000  补码
11111111 11111111 11111111 11110111  反码
10000000 00000000 00000000 00001000  原码 -8

Die Ausgabeergebnisse sind in der folgenden Abbildung dargestellt, die mit der Analyse übereinstimmt:
Bildbeschreibung hier einfügen

4.1 Übung 1

Es kann keine temporäre Variable (die dritte Variable) erstellt werden, um zwei Zahlen auszutauschen

int main()
{
    
    
	int a = 3;
	int b = 5;

	printf("a=%d b=%d\n", a, b);
	//第一种,常用的方法,创建中间变量
	int tmp = a;
	a = b;
	b = tmp;	
	//第二种,不创建变量
	a = a + b;
	b = a - b;
	a = a - b;
	//第三种,不创建变量,很难想到
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

4.2 Übung 2

Finden Sie die Anzahl der Einsen in der Binärzahl einer im Speicher gespeicherten Ganzzahl

//举例: 5   &1, 然后右移1位, 再&1
//00000000 00000000 00000000 00000101
//00000000 00000000 00000000 00000001
int main()
{
    
    
	int num = 0;
	scanf("%d", &num);
	int i = 0;
	int cnt = 0;
	//位操作
	for ( i = 0; i < 32; i++)
	{
    
    //每次右移一位就 &1
		if (1==((num>>i)&1))
		{
    
    
			cnt++;//所有位与1,相同为1,相异为0
		}
	}
	printf("%d", cnt);
	return 0;
}

Zusammenfassen

Dieser Artikel stellt den spezifischen Implementierungsprozess des Operators vor, stellt ihn vor und analysiert ihn. Es reicht aus, das Prinzip hier zu verstehen. Die spezifische Operation wird zur Ausführung an den Computer übergeben. Es ist nicht erforderlich, sie einzeln zu zeichnen und zu analysieren Fehler, 32-Bit-Binärdaten sollten in 4-Byte- und 8-Bit-Gruppen unterteilt werden, die besser aussehen.Dies wird häufig auf diese Weise unterteilt, wenn die STM32-MCU mit Registern arbeitet, was auf einen Blick klar ist.

Weitere Informationen zu Operatoren finden Sie im nächsten Artikel.

Ich denke du magst

Origin blog.csdn.net/taibudong1991/article/details/123855462
Empfohlen
Rangfolge