■1.【チルダ~】対【ビックリマーク!】
●ビット反転【チルダ~】
1 ⇒~ビット反転 ⇒0xFFFFfffE(2進数1111…0)
0 ⇒~ビット反転 ⇒0xFFFFfffF(2進数1111…1)
●論理反転【ビックリマーク!】
1 (真)⇒!論理反転 ⇒0(偽)
0 (偽)⇒!論理反転 ⇒1(真)
■2.&&でなくて&でしょう
warning: ‘~’ on a boolean expression
警告:ブール式で’~’チルダが使われた
[-Wbool-operation]
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
void f1(uint32_t x,uint32_t y)
{
uint32_t z;
z = ~(x && y); //NG
printf("%x\n",z);
z = ~(x & y); //OK
printf("%x\n",z);
}
~ビット反転と!論理否定とは違います。
論理式に対して~演算子を使用してビット反転するのは
誤りの可能性があります。
多分
&&ではなくて
& でしょう
■3.~でなくて!でしょう
void f2(bool x,bool y)
{
bool z;
z = ~(x && y); //NG
printf("%x\n",z);
z = !(x && y); //OK
printf("%x\n",z);
}
論理式に対して~演算子を使用してビット反転するのは
誤りの可能性があります。
多分~ではなくて!でしょう
■4.bool型変数に~演算子?
void f3(bool x)
{
//怪しい:bool型のビット反転
printf("%x\n",~x); //NG
//以下のどちらかにしかならない
//->ffffffff
//->fffffffe
printf("%x\n",!x);
}
bool型変数に対して~演算子を使用してビット反転すると
0xffffffff か
0xfffffffe にしかならないので
誤りの可能性があります。
多分~ではなくて!でしょう
■5.16進数定数に!演算子?
void f4(void)
{
uint32_t x = !0x2;//NG:16進数を論理反転
printf("%x\n",x);
uint32_t y = ~0x2 ;//OK
printf("%x\n",y);
}
16進数定数を!演算子を使用して論理反転するのは
誤りの可能性があります。
多分!ではなくて~でしょう。
#残念ながらgcc/clangで警告は現状でません。
■6.is系関数に~チルダを使用
#include <stdio.h>
#include <ctype.h>
//X<ctype.h>のis系関数に~チルダを使用
void 間違い(char *string){
for(char *p = string ; *p;p++){
if(~isalpha(*p)){
printf("%s:アルファベットじゃない %c\n",__func__,*p);
}
}
}
//◎<ctype.h>のis系関数に!ビックリを使用
void 正解(char *string){
for(char *p = string; *p;p++){
if(!isalpha(*p)){
printf("%s:アルファベットじゃない %c\n",__func__,*p);
}
}
}
int main(void){
static char *string = "abc123def456?#$%&";
間違い(string);
puts("--------");
正解(string);
}
<ctype.h>で提供されているis系関数に対して
ビット演算子の~を使用するのは恐らく間違いでしょう。
■7.練習問題:何と表示されますか?
#include <stdio.h>
#include <stdbool.h>
//ド・モルガンの法則実装誤り
static void 誤り(bool x,bool y){
if((~x && ~y) == ~(x || y)) puts("同じ");
else puts("違う");
if((~x || ~y) == ~(x && y)) puts("同じ");
else puts("違う");
}
//ド・モルガンの法則実装正解
static void 正解(bool x,bool y){
if((!x && !y) == !(x || y)) puts("同じ");
else puts("違う");
if((!x || !y) == !(x && y)) puts("同じ");
else puts("違う");
}
int main(void){
誤り(0,0);
誤り(0,1);
誤り(1,0);
誤り(1,1);
正解(0,0);
正解(0,1);
正解(1,0);
正解(1,1);
}