初級C言語 - 演算子の詳細 (1)

こんにちは、また会いました。最近コードを出力していますか?コーディング能力は向上しましたか? 今日は演算子を一緒に学びましょう。演算子は言語学習において非常に重要です。各演算子の機能と使い方を知る必要があります。学習を始めましょう。

  1. オペレーターの分類:

算術演算子
シフト演算子
ビット演算子 代入
演算子
単項演算子
関係演算子
論理演算子
条件演算子カンマ式
添字
参照、関数呼び出し、および構造体メンバー

2 つの算術演算子

     +    -   *   /     %

足し算(+) 引き算(-) 掛け算(*)は数学と同じですが、割り算(/)と剰余(%)の使い方についてお話します。

#include<stdio.h>
int main()
{
    
    
	float a = 5 / 2;
	printf("%f", a);
	return 0;
}

ここに画像の説明を挿入
浮動小数点型であるにもかかわらず、期待どおりの結果が得られないことがわかります。これはなぜでしょうか。

その理由は、小数点以下の数字が必要な場合、5 と 2 には 5.0 や 2.0 などの小数が必要であるため、それを加算して結果を確認してみましょう。

#include<stdio.h>
int main()
{
    
    
	float a = 5 .0/ 2;
	printf("%f", a);
	return 0;
}

ここに画像の説明を挿入
そしてモジュロ表記

まず、モジュロ記号の左辺と右辺は整数でなければならず、結果は剰余になります。

#include<stdio.h>
int main()
{
    
    
	int a = 9 % 2;
	printf("%d", a);
	return 0;
}

それは正しい

1. % 演算子に加えて、他のいくつかの演算子が整数と浮動小数点数に作用します。
2. / 演算子の場合、両方のオペランドが整数の場合、整数の除算が実行されます。そして、浮動小数点数が存在する限り、浮動小数点数の除算が実行されます。
3. % 演算子の 2 つのオペランドは整数である必要があります。除算後の剰余を返します。

3. シフト演算子

シフト演算子について話すとき、最初に 1 つのことを理解する必要があります。それは、シフト演算子が 2 の補数で動作するため、バイナリであるということです。

整数はバイナリで表現できます. 整数のバイナリ表現には,元の
コード,
コード, 補数コードの 3 つの形式があります. 逆コードとは, 元のコードの符号ビットはそのままで, 残りを反転したものです.ビットごとに、補数コードは逆コードに 1 を加えたものになります。


バイナリをより深く理解するために、いくつかの例を示します。

2 進数の計算は理解できないかもしれませんが、10 進数については知っておく必要があります。10 進数は私たちの生活でよく使われる数字です。小数がいっぱいになると 9 から 10 になります。すると、2 進数も同じになります。 2 がいっぱいになると前に進みます。1 ビット、たとえば 111 は 10 進数で 7 であり、
ここに画像の説明を挿入
計算結果は私たちがよく使う 10 進数になります。

2 レベル システムについては簡単に理解できましたので、元のコードの補数を見てみましょう。正の整数の元のコードの補数は
ここに画像の説明を挿入
同じです。たとえば、5 の元のコードは次のようになります。

0000000000000000000000000000101 元のコード
00000000000000000000000000000101 逆コード
00000000000000000000000000000101 補完コード

そして、シフト演算子は2 の補数を演算する
左シフト演算子 <<です。

#include<stdio.h>
int main()
{
    
    
	int a = 5<<1;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入
ここに画像の説明を挿入

正の整数の左シフト演算子を学び、負の数について学びましょう

#include<stdio.h>
int main()
{
    
    
	int a = -5 << 1;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入
この説明は誰もが理解する必要があるため、左シフトのルールは、右側を破棄して左側に 0 を追加することです。
右シフト演算子 >>
右シフト演算子は左シフト演算子と似ています

  1. 論理シフトは
    左側を 0 で埋め、右側を破棄します。
  2. 算術シフト
    左側は元の値の符号ビットで埋められ、右側は破棄されます

ここに例があります

#include<stdio.h>
int main()
{
    
    
	int a = 5 >> 1;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入
算術シフトの右側は符号ビットです

補足:補数コードは逆コードとなり、反転してから1を加算することもでき、符号ビットは変わりません。

警告: シフト演算子の場合、負のビットをシフトしないでください。これは標準では定義されていません。

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

4. ビット演算子

& //按位与
| //按位或
^ //按位异或

まず第一に、それらは整数を操作します

  • ビットごとの AND&
#include<stdio.h>
int main()
{
    
    
	int a = 5 & 3;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入
ここでのビットごとの AND はこのように理解できます。まず、上記と同じように 2 進数のビットを書き出してから、それらを整列する必要があります。0 が 1 つあれば結果は 0、1 はすべて 1 になります。

  • ビット単位または |
#include<stdio.h>
int main()
{
    
    
	int a = -1|3;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入

したがって、1 とのビット単位の OR は 1 になります。

  • ビット単位の XOR
#include<stdio.h>
int main()
{
    
    
	int a = -1^3;

	printf("%d", a);
	return 0;
}

ここに画像の説明を挿入

このようにして、ビット単位の演算子について理解しました。これらの演算子はすべて両眼演算子であることを付け加えておきます。両眼演算子とは何ですか? たとえば、3&5、& の両側のオペランドはそれぞれ 3 と 5 です。その場合、& は a です。双眼演算子です。& を見たとき、アドレス記号を取得することを考えますか? もちろん、それらは異なるはずです。アドレス & を取得することは単項演算子です。

以下は筆記試験問題です。数値を交換するための一時変数 (3 番目の一時変数) を作成することはできません。

#include<stdio.h>
int main()

{
    
    
	int a = 20;
	int b = 10;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("%d %d", a, b);
	return 0;
}

5. 代入演算子

int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值。
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试。

したがって、変数に値を代入するときは、少なくとも人々に理解してもらう必要があります。a = x = y+1このコードのように、最初に y+1 を x に代入し、次に y に代入します。この種の可読性は代入を分離するものではなく、代入
演算子
ここに画像の説明を挿入
6. 単項演算子
ここに画像の説明を挿入

論理反転

これは、true を false に変えることと、false を true に変えることと同じです。たとえば、if 関数の (1) が true の場合、それを追加すると! (!1) が論理偽の場合になります

負の値と正の値
、コードを挿入すると誰もがすぐに理解できます

#include<stdio.h>
int main()
{
    
    
	int a = -4;
	printf("%d", -a);
	return 0;
}

コンパイラによって表示される答えは、
正の値 4 は正の数と同じであるというものです。

  • .アドレスを取得&

メモリ内の変数の位置を取り出すことです

  • のサイズ
#include <stdio.h>
int main()
{
    
    
 int a = -10;
 int *p = NULL;//定义为空指针
 printf("%d\n", !2);
 printf("%d\n", !0);
 a = -a;
 p = &a;
 printf("%d\n", sizeof(a));
 printf("%d\n", sizeof(int));
 printf("%d\n", sizeof a);//这样写行不行?可以
 printf("%d\n", sizeof int);//这样写行不行?答案是不能
 return 0;
}

X86 コンパイラでのアドレスのバイト サイズは 4 ビットで、64 ビット プラットフォームでのバイト サイズは 8 ビットです。

sizeof で最も難しいのは、配列との組み合わせです。常に誤解を招く可能性があるため、例を示します。

#include <stdio.h>
void test1(int arr[])
{
    
    
	printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
    
    
	printf("%d\n", sizeof(ch));//(4)
}
int main()
{
    
    
	int arr[10] = {
    
     0 };
	char ch[10] = {
    
     0 };
	printf("%d\n", sizeof(arr));//(1)
	printf("%d\n", sizeof(ch));//(3)
	test1(arr);
	test2(ch);
	return 0;
}
//问:
//(1)、(2)两个地方分别输出多少?
//(3)、(4)两个地方分别输出多少?

ここに画像の説明を挿入
配列を渡すときに関数で渡される最初の要素のアドレスがわかれば理解できると思います 前回の記事でも具体的にお話しました 分からない方はそのままお楽しみください。

  • ~
    はビットごとの反転であり、2 進数の 1 の部分を 0 に、0 の部分を 1 に変換するのと同じです。
#include<stdio.h>
int main()
{
    
    
	int a = 2;
	printf("%d", ~a);
	return 0;
}

ここに画像の説明を挿入

- ++ と – を
++ または – の前に追加してから使用します

#include<stdio.h>
int main()
{
    
    

	int a = 1;
	int b = ++a;//a=a+1 b=a
	printf("%d %d", a, b);
	return 0;
}
#include<stdio.h>
int main()
{
    
    

	int a = 1;
	int b = --a;//a=a-1 b=a
	printf("%d %d", a, b);
	return 0;
}

後置 ++ および –


#include<stdio.h>
int main()
{
    
    

	int a = 1;
	int b = a++;//b=a a=a+1
	printf("%d %d", a, b);
	return 0;
}
#include<stdio.h>
int main()
{
    
    

	int a = 1;
	int b = a--;//b=a a=a-1
	printf("%d %d", a, b);
	return 0;
}

逆参照演算子*

一般にポインタで使用されます。たとえば、ポインタ変数の内容を知りたい場合、* を使用してその内容を知ることができます。これは、アドレスを取得する & の逆であることがわかりますか?

() この記号は、簡単な例では必須の変換です。


#include<stdio.h>
int main()
{
    
    
	float a = 5.0;
	int c = (int)a / 2;
	printf("%d", c);
	return 0;
}

浮動小数点型ですが、強制後、最後の a は整数になります

  • 7. 関係演算子
    ここに画像の説明を挿入

警告: == と = を必ず区別してください。
今日の共有はこれで終わりです。次回お会いできるのを楽しみにしています

おすすめ

転載: blog.csdn.net/2301_76895050/article/details/131574132