1.一時変数を作成せずに2つの数値を交換します
ここにaとbの値を入力します。交換する一時変数tmpを作成することはできません。
最初:
#include<stdio.h>
int main()
{
int a, b = 0;
scanf("%d%d", &a, &b);
a = a + b;
b = a - b;//此时b=a+b-b=a
a = a - b;//此时a=a+b-a=b实现了交换a ,b的目的
printf("a=%d b=%d",a,b);
return 0;
}
(aとbが大きい場合、a + bの値がint型シェーピングの範囲を超え、a + bの値が失われるため、このアルゴリズムには問題があることに注意してください)
2番目のタイプ:
#include<stdio.h>
int main()
{
int a, b = 0;
scanf("%d%d", &a, &b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a=%d b=%d",a,b);
return 0;
}
これはa = -1、b = 4の例です
交換を実現する
2.バイナリで1の桁数を見つけます
方法1:
数値%2は2進数を取得し、数値を2で割って次の桁を見つけます。
/ 2の後の最後の桁が0になるまで、falseの場合はループが停止します
#include<stdio.h>
int main()
{
int count = 0;
int n = 0;
scanf("%d",&n);
while (n)
{
if (n % 2 == 1)
count++;
n = n / 2;
}
printf("二进制位中1的个数为%d",count);
return 0;
}
しかし、ここに欠陥があり、負の数の2進数は計算できません
余りが-1の場合、負の数%2はcount ++を実行しません
方法2:
&演算子を知っています
バイナリでは、1&0 = 0、1&1 = 1のみ
1コンピュータに保存されているのは000000000 ... 1
したがって、2進数&1を入力します
1を取得した場合、バイナリビットの最後のビットが1であり、変数>> 1であることを意味します。
次の2進数が0かどうかを確認するには、合計32回です。
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d",&a);
int count = 0;
for (int i = 0; i < 32; i++)
{
int j = 1;
if ((a & j) == 1)
{
count++;
}
a = a >> 1;
}
printf("二进制中1的个数%d",count);
return 0;
}
このとき、負のバイナリビット1の数も計算できます。
方法3:
ビット単位のAND演算に2つの隣接するデータを使用する
#include<stdio.h>
int main()
{
int a = 0;
scanf("%d",&a);
int count = 0;
while (a)
{
a = a & (a - 1);
count++;
}
printf("二进制位为1的个数为%d",count);
return 0;
}
a = 3の場合
aの2進数は01 1a
-1です
。2進数は01 0 -------- a&a-1は0 1 0(count = 1)
その後、aの2進数は0 1 0
------ a-1の2進数は00 1
-------------- a&a-1は0 0 0( count = 2)
この時点で、a = 0はループからの誤ったジャンプです。
バイナリビットに複数の1がある場合、同じバイナリビットが存在する必要があるため、a&(a-1)を0にすることはできません。
最後のビットが1の場合、a&a-1
の最後のビットは0になり、aに割り当てることは、ビットを移動することと同じです。最後のビットが0の場合、a&a-1の最後のビットは0であり、aに割り当てます。 Aを破棄するのと同じです
2進数に1が1つしかない場合、a&a-1は0でなければならず、カウントは1ずつ増加してループを離れます。最終的なカウントは、aの2進数1の数です。
3.2桁の2進数で異なる数の数を見つけます
まず、2進数には0と1の2つの状況があることがわかっています。
まず、排他的論理和演算を使用して、さまざまな数値を1に変更し、変数cに格納します。
変数cの2進数1の数を計算する際、ここでは2進数1の数は繰り返されません。
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
scanf("%d%d",&a,&b);
int c = a ^ b;
int count = 0;
for (int i = 0; i < 32; i++)
{
int j = 1;
if ((c & j) == 1)
{
count++;
}
c = c >> 1;
}
printf("%d",count);
return 0;
}
4.発現評価
式の評価の一部は、演算子の優先順位と結合性の順に実行されます
優先度の高い方が先に計算されます。式の優先度が同じ場合、計算方向は結合法則に基づいているため、ここでは繰り返しません。
同時に、式のオペランドが他の型に変換される場合があります
シェーピング変換(非表示型変換)
例えば:
#include<stdio.h>
int main()
{
char a = 3;
char b = 137;
char c = a + b;
printf("%d",c);
return 0;
}
これは私たちが思っていたものではないことがわかりました140、
これは、char型のサイズが1バイトで、整数が4バイトであるためです。
char-8ビット、
int-32ビット、
整数の昇格は符号ビットに従って昇格されます。符号ビットはバイナリビットの最初のビットです。
+演算子はint型で動作するため、char型は最初に32ビットで埋められます
a = 0 0 0 0 0 0 1 1(補数、符号ビットは0)
a = 0000…01 1(32ビット)
b = 1 1 1 1 1 1 1 1(補数)
b = 0 0 0 0 0 0 1 1 1 1 1 1 1(32ビット)
a + b = 00…10 0 0 0 0 1 0(32ビット)
c = a + b(cは文字タイプであり、8ビットしか格納できないため、切り捨てが発生します)
c = 1 0 0 0 0 0 1 0
printf( "%d")なので、cを可塑化してプロモートする必要があります
cの符号ビットは1なので、1〜32ビットを追加します
整数昇格後のc
1 1 1 1 11…10 0 0 0 0 1 0(32ビット)(補数コード)
1 1 1 1 11…10 0 0 0 0 0 1(32ビット)(補数コード)
1 0 0 0 00…01 1 1 1 1 1 0(32ビット)(元のコード)
符号ビットが1の場合は、負の数であることを意味し
ます。元のコードは-116です。
一部の数値が符号なし桁の場合、整数の昇格はゼロを追加します。
整数の昇格は、2桁の数字があり、サイズがintよりも小さい場合にのみ発生します。
整数昇格が発生しました。
これは、intからintより大きい型に変換する場合には発生せず、切り捨てられません。
コンピュータは式の計算において必ずしも一意ではありません
例えば:
a*b+c*d+e*f
a b、c d、e * bを計算してから、3つを足し合わせることができます。
または、全体としてb + c dを取り、最初に計算し、次にe * fを計算し、次にそれを合計します。
したがって、式の操作は必ずしも一意であるとは限らず、この状況を回避するように注意する必要があります。
例えば:int c=(++a)+(++a)+(++a);
#include<stdio.h>
int main()
{
int a = 4;
int c = (++a) + (++a) + (++a);
printf("%d",c);
}
ここでの計算は、最初に++ aを3回計算し、a = 7で、合計は21です。
ただし、コンパイラが異なれば計算順序も異なります。++ aを2回計算し(最初の2つの式全体を使用)、計算後に+(++ a)を計算することもできます。
計算式が複雑すぎるので、計算式に入る必要はありません。