Last Update 2023/05/29
テスト概要
後置演算子
単項演算子
[ ] 配列の添え字
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* 配列の添え字 */
int a[3] = { 1, 2, 3 };
int b[3][3] = /* 2次元配列 */
{
{ 11, 12, 13 },
{ 21, 22, 23 },
{ 31, 32, 33 }
};
int c[2][2][2] = /* 3次元配列 */
{
{
{ 111, 112 },
{ 121, 122 },
},
{
{ 211, 212 },
{ 221, 222 }
}
};
printf("a[1] = %d\n", a[1]);
printf("a[2] = %d\n", a[2]);
printf("*(a + 1) = %d\n", *(a + 1)); <--- 上記配列使用の記述と等価
printf("*(a + 2) = %d\n\n", *(a + 2)); <--- 〃
printf("b[0][1] = %d\n", b[0][1]);
printf("b[1][2] = %d\n", b[1][2]);
printf("*(*(b + 0) + 1) = %d\n", *(*(b + 0) + 1)); <--- 上記配列使用の記述と等価
printf("*(*(b + 1) + 2) = %d\n\n", *(*(b + 1) + 2)); <--- 〃
printf("c[0][0][1] = %d\n", c[0][0][1]);
printf("c[1][1][0] = %d\n", c[1][1][0]);
printf("*(*(*(c + 0) + 0) + 1) = %d\n", *(*(*(c + 0) + 0) + 1)); <--- 上記配列使用の記述と等価
printf("*(*(*(c + 1) + 1) + 0) = %d\n", *(*(*(c + 1) + 1) + 0)); <--- 〃
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
a[1] = 2
a[2] = 3
*(a + 1) = 2
*(a + 2) = 3
b[0][1] = 12
b[1][2] = 23
*(*(b + 0) + 1) = 12
*(*(b + 1) + 2) = 23
c[0][0][1] = 112
c[1][1][0] = 221
*(*(*(c + 0) + 0) + 1) = 112
*(*(*(c + 1) + 1) + 0) = 221
( ) 関数呼び出し
sample.c
#include <stdio.h>
#include <stdlib.h>
/* 引数が空の関数 */
int sampfunc1(void) { return 1; }
/* 引数を伴う関数 */
int sampfunc2(int i1, int i2, char *s)
{
printf("s = %s : sizeof(i1) = %ld : sizeof(i2) = %ld\n",
s, sizeof(i1), sizeof(i2));
return i1 + i2;
}
int main(void)
{
unsigned char c = 1;
int n;
/* 関数呼び出し */
/* 引数が空の関数呼び出し */
printf("sampfunc1() = %d\n", sampfunc1());
/* 引数を伴う関数呼び出し */
n = sampfunc2(1, 2, "abc");
printf("n = %d\n", n);
/* 引数の型が宣言と異なる関数呼び出し(1) */
n = sampfunc2(1, c, "def");
printf("sizeof(c) = %ld : n = %d\n", sizeof(c), n);
/* 引数の型が宣言と異なる関数呼び出し(2) */
n = sampfunc2(1.5, 1.5, "ghi");
printf("sizeof(1.5) = %ld : n = %d\n", sizeof(1.5), n);
/* 関数ポインタによる呼び出し */
int (*fnp)(int, int, char *); /* 関数へのポインタの定義 */
fnp = sampfunc2; /* ポインタへのsampfunc2のアドレスの代入 */
n = fnp(1, 2, "jkl");
printf("n = %d\n", n);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
sampfunc1() = 1
s = abc : sizeof(i1) = 4 : sizeof(i2) = 4
n = 3
s = def : sizeof(i1) = 4 : sizeof(i2) = 4 <--- 1バイトのパラメータが関数プロトタイプの型(4バイト)に変換される
sizeof(c) = 1 : n = 2
s = ghi : sizeof(i1) = 4 : sizeof(i2) = 4
sizeof(1.5) = 8 : n = 2 <--- double型のパラメータが整数型(4バイト)に変換される(小数点以下切り捨て)
s = jkl : sizeof(i1) = 4 : sizeof(i2) = 4
n = 3
. ドット演算子
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* 構造体 */
struct samp_struct
{
char st_txt[10];
size_t st_len;
};
/* 共用体 */
union samp_union
{
unsigned long un_ulong;
unsigned int un_uint[2];
unsigned char un_uchar[8];
};
int main(void)
{
struct samp_struct ss = {"sample", 0}; /* 構造体オブジェクト */
union samp_union su; /* 共用体オブジェクト */
/* ドット演算子 */
/* [構造体オブジェクト].[構造体メンバ] */
ss.st_len = strlen(ss.st_txt);
printf("st_txt = %s : st_len = %ld\n", ss.st_txt, ss.st_len);
/* [共用体オブジェクト].[共用体メンバ] */
su.un_ulong = ULONG_MAX;
printf("un_ulong = %lX\n", su.un_ulong);
for (int i=0; i<8; i++)
{
su.un_uchar[i] = su.un_uchar[i] - i;
printf("un_uchar[%d] = %X\n", i, su.un_uchar[i]);
}
printf("un_ulong = %lX\n", su.un_ulong);
for (int i=0; i<2; i++)
{
printf("un_uint[%d] = %X\n", i, su.un_uint[i]);
}
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
st_txt = sample : st_len = 6
un_ulong = FFFFFFFFFFFFFFFF
un_uchar[0] = FF
un_uchar[1] = FE
un_uchar[2] = FD
un_uchar[3] = FC
un_uchar[4] = FB
un_uchar[5] = FA
un_uchar[6] = F9
un_uchar[7] = F8
un_ulong = F8F9FAFBFCFDFEFF
un_uint[0] = FCFDFEFF
un_uint[1] = F8F9FAFB
-> アロー演算子
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/* 構造体 */
struct samp_struct
{
char st_txt[10];
size_t st_len;
};
/* 共用体 */
union samp_union
{
unsigned long un_ulong;
unsigned int un_uint[2];
unsigned char un_uchar[8];
};
int main(void)
{
struct samp_struct ss = {"sample", 0}; /* 構造体オブジェクト */
union samp_union su; /* 共用体オブジェクト */
struct samp_struct *ssp = &ss; /* samp_structへのポインタ */
union samp_union *sup = &su; /* samp_unionへのポインタ */
/* アロー演算子 */
/* [構造体オブジェクト]->[構造体メンバ] */
ssp->st_len = strlen(ssp->st_txt);
printf("st_txt = %s : st_len = %ld\n", ssp->st_txt, ssp->st_len);
/* [共用体オブジェクト].[共用体メンバ] */
sup->un_ulong = ULONG_MAX;
printf("un_ulong = %lX\n", sup->un_ulong);
for (int i=0; i<8; i++)
{
sup->un_uchar[i] = sup->un_uchar[i] - i;
printf("un_uchar[%d] = %X\n", i, sup->un_uchar[i]);
}
printf("un_ulong = %lX\n", sup->un_ulong);
for (int i=0; i<2; i++)
{
printf("un_uint[%d] = %X\n", i, sup->un_uint[i]);
}
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
st_txt = sample : st_len = 6
un_ulong = FFFFFFFFFFFFFFFF
un_uchar[0] = FF
un_uchar[1] = FE
un_uchar[2] = FD
un_uchar[3] = FC
un_uchar[4] = FB
un_uchar[5] = FA
un_uchar[6] = F9
un_uchar[7] = F8
un_ulong = F8F9FAFBFCFDFEFF
un_uint[0] = FCFDFEFF
un_uint[1] = F8F9FAFB
複合リテラル
sample.c
#include <stdio.h>
#include <stdlib.h>
/* 関数外で定義された複合リテラル */
int *ip = (int []){10, 20, 30};
void samp_func(double *d)
{
while (*d > 0)
{
printf("d = %e\n", *d);
d++;
}
printf("ip = %d\n", *ip);
}
int main(void)
{
/* 複合リテラルを引数として関数呼び出し */
samp_func((double []){ 1.0, 2.0, -1.0 });
ip++;
samp_func((double []){ 4.0, -1.0 });
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
d = 1.000000e+00
d = 2.000000e+00
ip = 10
d = 4.000000e+00
ip = 20
後置++および--
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i1 = 3, i2 = 3;
int j1 = 3, j2 = 3;
/* 後置++ */
i1 = i1 + 1;
j1++;
printf("(1-1) i1 = %d, j1 = %d\n", i1, j1);
printf("(1-2) i1 = %d, j1++ = %d\n", i1, j1++);
printf("(1-3) i1 = %d, j1 = %d\n", i1, j1);
/* 後置-- */
i2 = i2 - 1;
j2--;
printf("(2-1) i2 = %d, j2 = %d\n", i2, j2);
printf("(2-2) i2 = %d, j2-- = %d\n", i2, j2--);
printf("(2-3) i2 = %d, j2 = %d\n", i2, j2);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
(1-1) i1 = 4, j1 = 4
(1-2) i1 = 4, j1++ = 4 <--- printf関数呼び出し時点では加算されていない
(1-3) i1 = 4, j1 = 5 <--- 上記コード実行後の加算を確認
(2-1) i2 = 2, j2 = 2
(2-2) i2 = 2, j2-- = 2 <--- printf関数呼び出し時点では減算されていない
(2-3) i2 = 2, j2 = 1 <--- 上記コード実行後の減算を確認
前置++および--
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i1 = 3, i2 = 3;
int j1 = 3, j2 = 3;
/* 前置++ */
i1 = i1 + 1;
++j1;
printf("(1-1) i1 = %d, j1 = %d\n", i1, j1);
printf("(1-2) i1 = %d, ++j1 = %d\n", i1, ++j1);
printf("(1-3) i1 = %d, j1 = %d\n", i1, j1);
/* 前置-- */
i2 = i2 - 1;
--j2;
printf("(2-1) i2 = %d, j2 = %d\n", i2, j2);
printf("(2-2) i2 = %d, --j2 = %d\n", i2, --j2);
printf("(2-3) i2 = %d, j2 = %d\n", i2, j2);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
(1-1) i1 = 4, j1 = 4
(1-2) i1 = 4, ++j1 = 5 <--- printf関数呼び出し時点で加算完了
(1-3) i1 = 4, j1 = 5 <--- 上記コード実行後、値の変化なし
(2-1) i2 = 2, j2 = 2
(2-2) i2 = 2, --j2 = 1 <--- printf関数呼び出し時点で減算完了
(2-3) i2 = 2, j2 = 1 <--- 上記コード実行後、値の変化なし
アドレス演算子 &、間接演算子 *
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i = 1;
/* 変数iの値とアドレス(アドレス演算子 &) */
printf("i = %d --- &i = %p\n", i, &i);
/* ポインタにアドレスを代入 */
int *pi = &i;
/* ポインタpiの値(アドレス)と参照するオブジェクト(間接演算子 *) */
printf("pi = %p --- *pi = %d\n", pi, *pi);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
i = 1 --- &i = 0x7ffccf393ff4
pi = 0x7ffccf393ff4 --- *pi = 1
単項演算子 + および -
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* 単項演算子 + */
printf("+1 = %d\n", +1);
printf("+(-1) = %d\n", +(-1));
/* 単項演算子 - */
printf("-1 = %d\n", -1);
printf("-(-1) = %d\n", -(-1));
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
+1 = 1 <--- オペランドの符号に変化なし
+(-1) = -1 <--- 〃
-1 = -1 <--- オペランドの算術否定
-(-1) = 1 <--- 〃
ビット否定演算子 ~
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(void)
{
/* ビット否定演算子 ~ */
printf("~0x00000000 = %X\n", ~0x00000000);
printf("~0x00000001 = %X\n", ~0x00000001);
printf("~0x80000001 = %X\n", ~0x80000001);
printf("~UINT_MAX = %X\n", ~UINT_MAX);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
~0x00000000 = FFFFFFFF <--- 1111...1111
~0x00000001 = FFFFFFFE <--- 1111...1110
~0x80000001 = 7FFFFFFE <--- 0111...1110
~UINT_MAX = 0 <--- 0000...0000
論理否定演算子 !
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* 論理否定演算子 ! */
printf("!0 = %d\n", !0);
printf("!1 = %d\n", !1);
printf("!!0 = %d\n", !!0);
printf("!!1 = %d\n", !!1);
printf("!!!0 = %d\n", !!!0);
printf("!!!1 = %d\n", !!!1);
printf("!(-1) = %d\n", !(-1));
printf("!2 = %d\n", !2);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
!0 = 1 <--- オペランドが0の場合は1
!1 = 0 <--- オペランドが1の場合は0
!!0 = 0 <--- !1と同じ
!!1 = 1 <--- !0と同じ
!!!0 = 1 <--- !!1と同じ
!!!1 = 0 <--- !!0と同じ
!(-1) = 0 <--- オペランドが0以外の場合は0
!2 = 0 <--- 〃
sizeof演算子
sample.c
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
char str[100]; /* 100 */
int n; /* 4 */
double d; /* 8 */
} sampstruct;
int main(void)
{
/* sizeof演算子 */
printf("sizeof(_Bool) = %ld\n", sizeof(_Bool));
printf("sizeof(_Float16) = %ld\n", sizeof(_Float16));
printf("sizeof(_Float32) = %ld\n", sizeof(_Float32));
printf("sizeof(_Float64) = %ld\n", sizeof(_Float64));
printf("sizeof(_Float128) = %ld\n", sizeof(_Float128));
printf("sizeof(_Float32x) = %ld\n", sizeof(_Float32x));
printf("sizeof(_Float64x) = %ld\n", sizeof(_Float64x));
printf("sizeof(_Decimal32) = %ld\n", sizeof(_Decimal32));
printf("sizeof(_Decimal64) = %ld\n", sizeof(_Decimal64));
printf("sizeof(_Decimal128) = %ld\n", sizeof(_Decimal128));
printf("sizeof(char) = %ld\n", sizeof(char));
printf("sizeof(signed char) = %ld\n", sizeof(signed char));
printf("sizeof(unsigned char) = %ld\n", sizeof(unsigned char));
printf("sizeof(short int) = %ld\n", sizeof(short int));
printf("sizeof(unsigned short int) = %ld\n", sizeof(unsigned short int));
printf("sizeof(signed int) = %ld\n", sizeof(signed int));
printf("sizeof(unsigned int) = %ld\n", sizeof(unsigned int));
printf("sizeof(signed long int) = %ld\n", sizeof(signed long int));
printf("sizeof(unsigned long int) = %ld\n", sizeof(unsigned long int));
printf("sizeof(signed long long int) = %ld\n", sizeof(signed long long int));
printf("sizeof(unsigned long long int) = %ld\n", sizeof(unsigned long long int));
printf("sizeof(float) = %ld\n", sizeof(float));
printf("sizeof(double) = %ld\n", sizeof(double));
printf("sizeof(long double) = %ld\n\n", sizeof(long double));
printf("sizeof(sampstruct) = %ld\n", sizeof(sampstruct));
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
sizeof(_Bool) = 1
sizeof(_Float16) = 2
sizeof(_Float32) = 4
sizeof(_Float64) = 8
sizeof(_Float128) = 16
sizeof(_Float32x) = 8
sizeof(_Float64x) = 16
sizeof(_Decimal32) = 4
sizeof(_Decimal64) = 8
sizeof(_Decimal128) = 16
sizeof(char) = 1
sizeof(signed char) = 1
sizeof(unsigned char) = 1
sizeof(short int) = 2
sizeof(unsigned short int) = 2
sizeof(signed int) = 4
sizeof(unsigned int) = 4
sizeof(signed long int) = 8
sizeof(unsigned long int) = 8
sizeof(signed long long int) = 8
sizeof(unsigned long long int) = 8
sizeof(float) = 4
sizeof(double) = 8
sizeof(long double) = 16
sizeof(sampstruct) = 112
_Alignof演算子
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int sample_int1 = 0;
/* _Alignas指定子によりアラインメントを定義したオブジェクト */
_Alignas(8) int sample_int2 = 0;
_Alignas(16) int sample_int3 = 0;
_Alignas(32) int sample_int4 = 0;
printf("_Alignof(_Bool) = %ld\n", _Alignof(_Bool));
printf("_Alignof(_Float16) = %ld\n", _Alignof(_Float16));
printf("_Alignof(_Float32) = %ld\n", _Alignof(_Float32));
printf("_Alignof(_Float64) = %ld\n", _Alignof(_Float64));
printf("_Alignof(_Float128) = %ld\n", _Alignof(_Float128));
printf("_Alignof(_Float32x) = %ld\n", _Alignof(_Float32x));
printf("_Alignof(_Float64x) = %ld\n", _Alignof(_Float64x));
printf("_Alignof(_Decimal32) = %ld\n", _Alignof(_Decimal32));
printf("_Alignof(_Decimal64) = %ld\n", _Alignof(_Decimal64));
printf("_Alignof(_Decimal128) = %ld\n", _Alignof(_Decimal128));
printf("_Alignof(char) = %ld\n", _Alignof(char));
printf("_Alignof(signed char) = %ld\n", _Alignof(signed char));
printf("_Alignof(unsigned char) = %ld\n", _Alignof(unsigned char));
printf("_Alignof(short int) = %ld\n", _Alignof(short int));
printf("_Alignof(unsigned short int) = %ld\n", _Alignof(unsigned short int));
printf("_Alignof(signed int) = %ld\n", _Alignof(signed int));
printf("_Alignof(unsigned int) = %ld\n", _Alignof(unsigned int));
printf("_Alignof(signed long int) = %ld\n", _Alignof(signed long int));
printf("_Alignof(unsigned long int) = %ld\n", _Alignof(unsigned long int));
printf("_Alignof(signed long long int) = %ld\n", _Alignof(signed long long int));
printf("_Alignof(unsigned long long int) = %ld\n", _Alignof(unsigned long long int));
printf("_Alignof(float) = %ld\n", _Alignof(float));
printf("_Alignof(double) = %ld\n", _Alignof(double));
printf("_Alignof(long double) = %ld\n\n", _Alignof(long double));
printf("_Alignof(sample_int1) = %ld\n", _Alignof(sample_int1));
printf("_Alignof(sample_int2) = %ld\n", _Alignof(sample_int2));
printf("_Alignof(sample_int3) = %ld\n", _Alignof(sample_int3));
printf("_Alignof(sample_int4) = %ld\n\n", _Alignof(sample_int4));
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
_Alignof(_Bool) = 1
_Alignof(_Float16) = 2
_Alignof(_Float32) = 4
_Alignof(_Float64) = 8
_Alignof(_Float128) = 16
_Alignof(_Float32x) = 8
_Alignof(_Float64x) = 16
_Alignof(_Decimal32) = 4
_Alignof(_Decimal64) = 8
_Alignof(_Decimal128) = 16
_Alignof(char) = 1
_Alignof(signed char) = 1
_Alignof(unsigned char) = 1
_Alignof(short int) = 2
_Alignof(unsigned short int) = 2
_Alignof(signed int) = 4
_Alignof(unsigned int) = 4
_Alignof(signed long int) = 8
_Alignof(unsigned long int) = 8
_Alignof(signed long long int) = 8
_Alignof(unsigned long long int) = 8
_Alignof(float) = 4
_Alignof(double) = 8
_Alignof(long double) = 16
_Alignof(sample_int1) = 4
_Alignof(sample_int2) = 8 <--- _Alignas指定子により定義された値
_Alignof(sample_int3) = 16 <--- 〃
_Alignof(sample_int4) = 32 <--- 〃
キャスト演算子
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* 型キャスト無しで整数型による演算・出力 */
printf("4 / 3 = %d\n", 4 / 3);
/* 演算後にdouble型に型キャスト */
printf("4 / 3 = %e\n", (double)(4 / 3));
/* 演算前の値をdouble型に型キャスト */
printf("4 / 3 = %e\n", (double)4 / 3);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
4 / 3 = 1 <--- 演算・結果共に整数
4 / 3 = 1.000000e+00 <--- 結果(整数)をキャストすることによりdoubleに変換
4 / 3 = 1.333333e+00 <--- 片方のオペランドがdoubleにキャストされたことにより、両オペランドがdoubleに統一され演算・結果共にdouble型
乗除演算子 * / %
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* 乗法演算子 */
printf("整数型 * 整数型 : 4 * 3 = %d\n", 4 * 3);
printf("浮動小数点型 * 浮動小数点型 : 4.0 * 3.0 = %f\n\n", 4.0 * 3.0);
/* 除法演算子 */
printf("整数型 / 整数型 : 4 / 3 = %d\n", 4 / 3);
printf("浮動小数点型 / 整数型 : 4.0 / 3 = %f\n", 4.0 / 3);
printf("浮動小数点型 / 浮動小数点型 : 4.0 / 3.0 = %f\n\n", 4.0 / 3.0);
/* 剰余演算子 */
printf("整数型 %% 整数型 : 4 %% 3 = %d\n", 4 % 3);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
整数型 * 整数型 : 4 * 3 = 12
浮動小数点型 * 浮動小数点型 : 4.0 * 3.0 = 12.000000
整数型 / 整数型 : 4 / 3 = 1
浮動小数点型 / 整数型 : 4.0 / 3 = 1.333333 <--- 算術型変換により整数型は浮動小数点型に変換後演算
浮動小数点型 / 浮動小数点型 : 4.0 / 3.0 = 1.333333
整数型 % 整数型 : 4 % 3 = 1
加減演算子 + -
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char c[10] = "abcdefg";
char *p = &c[3];
/* 加法演算子 */
printf("整数型 + 整数型 : 4 + 3 = %d\n", 4 + 3);
printf("浮動小数点型 + 整数型 : 4.5 + 3 = %f\n", 4.5 + 3);
printf("浮動小数点型 + 浮動小数点型 : 4.5 + 3.0 = %f\n", 4.5 + 3.0);
printf("ポインタ型 + 整数型 : p(%c) + 2 ---> %c\n\n", *p, *(p + 2));
/* 減法演算子 */
printf("整数型 - 整数型 : 4 - 3 = %d\n", 4 - 3);
printf("浮動小数点型 - 整数型 : 4.5 - 3 = %f\n", 4.5 - 3);
printf("浮動小数点型 - 浮動小数点型 : 4.5 - 3.5 = %f\n", 4.5 - 3.5);
printf("ポインタ型 - 整数型 : p(%c) - 2 ---> %c\n\n", *p, *(p - 2));
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
整数型 + 整数型 : 4 + 3 = 7
浮動小数点型 + 整数型 : 4.5 + 3 = 7.500000 <--- 算術型変換により整数型は浮動小数点型に変換後演算
浮動小数点型 + 浮動小数点型 : 4.5 + 3.0 = 7.500000
ポインタ型 + 整数型 : p(d) + 2 ---> f
整数型 - 整数型 : 4 - 3 = 1
浮動小数点型 - 整数型 : 4.5 - 3 = 1.500000 <--- 算術型変換により整数型は浮動小数点型に変換後演算
浮動小数点型 - 浮動小数点型 : 4.5 - 3.5 = 1.000000
ポインタ型 - 整数型 : p(d) - 2 ---> b
シフト演算子 << >>
sample.c
#include <stdio.h>
#include <stdlib.h>
/* 2進数出力用関数 */
void putbd(unsigned int n)
{
for (unsigned int i=0; i<4*8; i++)
{
putc('0' + (n & ((1u << (4*8-1)) >> i) ? 1 : 0), stdout);
}
}
int main(void)
{
unsigned int x = 1 << (4*8-1);
/* 左シフト */
printf("左シフト初期値整数 1\n");
for (int i=0; i<4*8; i++)
{
printf("1 << %2d %11u ", i, 1 << i);
putbd(1 << i);
putc('\n', stdout);
}
putc('\n', stdout);
/* 右シフト(符号無し整数) */
printf("右シフト初期値整数 x = %u(unsigned int)\n", x);
for (int i=0; i<4*8; i++)
{
printf("x >> %2d %11u ", i, x >> i);
putbd(x >> i);
putc('\n', stdout);
}
putc('\n', stdout);
/* 右シフト(符号付き整数) */
printf("右シフト初期値整数 x = %d(int)\n", (int)x);
for (int i=0; i<4*8; i++)
{
printf("(int)x >> %2d %11d ", i, (int)x >> i);
putbd((int)x >> i);
putc('\n', stdout);
}
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
左シフト初期値整数 1
1 << 0 1 00000000000000000000000000000001
1 << 1 2 00000000000000000000000000000010
1 << 2 4 00000000000000000000000000000100
1 << 3 8 00000000000000000000000000001000
1 << 4 16 00000000000000000000000000010000
1 << 5 32 00000000000000000000000000100000
1 << 6 64 00000000000000000000000001000000
1 << 7 128 00000000000000000000000010000000
1 << 8 256 00000000000000000000000100000000
1 << 9 512 00000000000000000000001000000000
1 << 10 1024 00000000000000000000010000000000
1 << 11 2048 00000000000000000000100000000000
1 << 12 4096 00000000000000000001000000000000
1 << 13 8192 00000000000000000010000000000000
1 << 14 16384 00000000000000000100000000000000
1 << 15 32768 00000000000000001000000000000000
1 << 16 65536 00000000000000010000000000000000
1 << 17 131072 00000000000000100000000000000000
1 << 18 262144 00000000000001000000000000000000
1 << 19 524288 00000000000010000000000000000000
1 << 20 1048576 00000000000100000000000000000000
1 << 21 2097152 00000000001000000000000000000000
1 << 22 4194304 00000000010000000000000000000000
1 << 23 8388608 00000000100000000000000000000000
1 << 24 16777216 00000001000000000000000000000000
1 << 25 33554432 00000010000000000000000000000000
1 << 26 67108864 00000100000000000000000000000000
1 << 27 134217728 00001000000000000000000000000000
1 << 28 268435456 00010000000000000000000000000000
1 << 29 536870912 00100000000000000000000000000000
1 << 30 1073741824 01000000000000000000000000000000
1 << 31 2147483648 10000000000000000000000000000000
右シフト初期値整数 x = 2147483648(unsigned int)
x >> 0 2147483648 10000000000000000000000000000000
x >> 1 1073741824 01000000000000000000000000000000
x >> 2 536870912 00100000000000000000000000000000
x >> 3 268435456 00010000000000000000000000000000
x >> 4 134217728 00001000000000000000000000000000
x >> 5 67108864 00000100000000000000000000000000
x >> 6 33554432 00000010000000000000000000000000
x >> 7 16777216 00000001000000000000000000000000
x >> 8 8388608 00000000100000000000000000000000
x >> 9 4194304 00000000010000000000000000000000
x >> 10 2097152 00000000001000000000000000000000
x >> 11 1048576 00000000000100000000000000000000
x >> 12 524288 00000000000010000000000000000000
x >> 13 262144 00000000000001000000000000000000
x >> 14 131072 00000000000000100000000000000000
x >> 15 65536 00000000000000010000000000000000
x >> 16 32768 00000000000000001000000000000000
x >> 17 16384 00000000000000000100000000000000
x >> 18 8192 00000000000000000010000000000000
x >> 19 4096 00000000000000000001000000000000
x >> 20 2048 00000000000000000000100000000000
x >> 21 1024 00000000000000000000010000000000
x >> 22 512 00000000000000000000001000000000
x >> 23 256 00000000000000000000000100000000
x >> 24 128 00000000000000000000000010000000
x >> 25 64 00000000000000000000000001000000
x >> 26 32 00000000000000000000000000100000
x >> 27 16 00000000000000000000000000010000
x >> 28 8 00000000000000000000000000001000
x >> 29 4 00000000000000000000000000000100
x >> 30 2 00000000000000000000000000000010
x >> 31 1 00000000000000000000000000000001
右シフト初期値整数 x = -2147483648(int)
(int)x >> 0 -2147483648 10000000000000000000000000000000
(int)x >> 1 -1073741824 11000000000000000000000000000000
(int)x >> 2 -536870912 11100000000000000000000000000000
(int)x >> 3 -268435456 11110000000000000000000000000000
(int)x >> 4 -134217728 11111000000000000000000000000000
(int)x >> 5 -67108864 11111100000000000000000000000000
(int)x >> 6 -33554432 11111110000000000000000000000000
(int)x >> 7 -16777216 11111111000000000000000000000000
(int)x >> 8 -8388608 11111111100000000000000000000000
(int)x >> 9 -4194304 11111111110000000000000000000000
(int)x >> 10 -2097152 11111111111000000000000000000000
(int)x >> 11 -1048576 11111111111100000000000000000000
(int)x >> 12 -524288 11111111111110000000000000000000
(int)x >> 13 -262144 11111111111111000000000000000000
(int)x >> 14 -131072 11111111111111100000000000000000
(int)x >> 15 -65536 11111111111111110000000000000000
(int)x >> 16 -32768 11111111111111111000000000000000
(int)x >> 17 -16384 11111111111111111100000000000000
(int)x >> 18 -8192 11111111111111111110000000000000
(int)x >> 19 -4096 11111111111111111111000000000000
(int)x >> 20 -2048 11111111111111111111100000000000
(int)x >> 21 -1024 11111111111111111111110000000000
(int)x >> 22 -512 11111111111111111111111000000000
(int)x >> 23 -256 11111111111111111111111100000000
(int)x >> 24 -128 11111111111111111111111110000000
(int)x >> 25 -64 11111111111111111111111111000000
(int)x >> 26 -32 11111111111111111111111111100000
(int)x >> 27 -16 11111111111111111111111111110000
(int)x >> 28 -8 11111111111111111111111111111000
(int)x >> 29 -4 11111111111111111111111111111100
(int)x >> 30 -2 11111111111111111111111111111110
(int)x >> 31 -1 11111111111111111111111111111111
関係演算子 < > <= >=
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i1 = 1;
int i2 = 2;
int i3 = 1;
double d1 = 1.0;
double d2 = 2.0;
double d3 = 1.0;
int n[2] = {1, 2};
int *p1 = &n[0];
int *p2 = &n[1];
int *p3 = &n[0];
printf("関係演算子 真:1 偽:0\n\n");
printf("1 (int) < 2 (int) --- i1 < i2 --> %d\n", i1 < i2);
printf("1 (int) < 1 (int) --- i1 < i3 --> %d\n", i1 < i3);
printf("1.0 (double) < 2.0 (double) --- d1 < d2 --> %d\n", d1 < d2);
printf("1.0 (double) < 1.0 (double) --- d1 < d3 --> %d\n", d1 < d3);
printf("1 (int) < 2.0 (double) --- i1 < d2 --> %d\n", i1 < d2);
printf("1 (int) < 1.0 (double) --- i1 < d1 --> %d\n", i1 < d3);
printf("&n[0] (int *) < &n[1] (int *) --- p1 < p2 --> %d\n", p1 < p2);
printf("&n[0] (int *) < &n[0] (int *) --- p1 < p3 --> %d\n\n", p1 < p3);
printf("2 (int) > 1 (int) --- i2 > i1 --> %d\n", i2 > i1);
printf("1 (int) > 1 (int) --- i1 > i3 --> %d\n", i1 > i3);
printf("2.0 (double) > 1.0 (double) --- d2 > d1 --> %d\n", d2 > d1);
printf("1.0 (double) > 1.0 (double) --- d3 > d1 --> %d\n", d3 > d1);
printf("2 (int) > 1.0 (double) --- i2 > d1 --> %d\n", i2 > d1);
printf("1 (int) > 1.0 (double) --- i1 > d1 --> %d\n", i1 > d1);
printf("&n[1] (int *) > &n[0] (int *) --- p2 > p1 --> %d\n", p2 > p1);
printf("&n[0] (int *) > &n[0] (int *) --- p1 > p3 --> %d\n\n", p1 > p3);
printf("1 (int) <= 2 (int) --- i1 <= i2 --> %d\n", i1 <= i2);
printf("1 (int) <= 1 (int) --- i1 <= i3 --> %d\n", i1 <= i3);
printf("1.0 (double) <= 2.0 (double) --- d1 <= d2 --> %d\n", d1 <= d2);
printf("1.0 (double) <= 1.0 (double) --- d1 <= d3 --> %d\n", d1 <= d3);
printf("1 (int) <= 2.0 (double) --- i1 <= d2 --> %d\n", i1 <= d2);
printf("1 (int) <= 1.0 (double) --- i1 <= d1 --> %d\n", i1 <= d3);
printf("&n[0] (int *) <= &n[1] (int *) --- p1 <= p2 --> %d\n", p1 <= p2);
printf("&n[0] (int *) <= &n[0] (int *) --- p1 <= p3 --> %d\n\n", p1 <= p3);
printf("2 (int) >= 1 (int) --- i2 >= i1 --> %d\n", i2 >= i1);
printf("1 (int) >= 1 (int) --- i1 >= i3 --> %d\n", i1 >= i3);
printf("2.0 (double) >= 1.0 (double) --- d2 >= d1 --> %d\n", d2 >= d1);
printf("1.0 (double) >= 1.0 (double) --- d3 >= d1 --> %d\n", d3 >= d1);
printf("2 (int) >= 1.0 (double) --- i2 >= d1 --> %d\n", i2 >= d1);
printf("1 (int) >= 1.0 (double) --- i1 >= d1 --> %d\n", i1 >= d1);
printf("&n[1] (int *) >= &n[0] (int *) --- p2 >= p1 --> %d\n", p1 <= p2);
printf("&n[0] (int *) >= &n[0] (int *) --- p1 >= p3 --> %d\n\n", p1 <= p3);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
関係演算子 真:1 偽:0
1 (int) < 2 (int) --- i1 < i2 --> 1
1 (int) < 1 (int) --- i1 < i3 --> 0
1.0 (double) < 2.0 (double) --- d1 < d2 --> 1
1.0 (double) < 1.0 (double) --- d1 < d3 --> 0
1 (int) < 2.0 (double) --- i1 < d2 --> 1
1 (int) < 1.0 (double) --- i1 < d1 --> 0
&n[0] (int *) < &n[1] (int *) --- p1 < p2 --> 1
&n[0] (int *) < &n[0] (int *) --- p1 < p3 --> 0
2 (int) > 1 (int) --- i2 > i1 --> 1
1 (int) > 1 (int) --- i1 > i3 --> 0
2.0 (double) > 1.0 (double) --- d2 > d1 --> 1
1.0 (double) > 1.0 (double) --- d3 > d1 --> 0
2 (int) > 1.0 (double) --- i2 > d1 --> 1
1 (int) > 1.0 (double) --- i1 > d1 --> 0
&n[1] (int *) > &n[0] (int *) --- p2 > p1 --> 1
&n[0] (int *) > &n[0] (int *) --- p1 > p3 --> 0
1 (int) <= 2 (int) --- i1 <= i2 --> 1
1 (int) <= 1 (int) --- i1 <= i3 --> 1
1.0 (double) <= 2.0 (double) --- d1 <= d2 --> 1
1.0 (double) <= 1.0 (double) --- d1 <= d3 --> 1
1 (int) <= 2.0 (double) --- i1 <= d2 --> 1
1 (int) <= 1.0 (double) --- i1 <= d1 --> 1
&n[0] (int *) <= &n[1] (int *) --- p1 <= p2 --> 1
&n[0] (int *) <= &n[0] (int *) --- p1 <= p3 --> 1
2 (int) >= 1 (int) --- i2 >= i1 --> 1
1 (int) >= 1 (int) --- i1 >= i3 --> 1
2.0 (double) >= 1.0 (double) --- d2 >= d1 --> 1
1.0 (double) >= 1.0 (double) --- d3 >= d1 --> 1
2 (int) >= 1.0 (double) --- i2 >= d1 --> 1
1 (int) >= 1.0 (double) --- i1 >= d1 --> 1
&n[1] (int *) >= &n[0] (int *) --- p2 >= p1 --> 1
&n[0] (int *) >= &n[0] (int *) --- p1 >= p3 --> 1
等価演算子 == !=
sample.c
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i1 = 1;
int i2 = 2;
int i3 = 1;
double d1 = 1.0;
double d2 = 2.0;
double d3 = 1.0;
int n[2] = {1, 2};
int *p1 = &n[0];
int *p2 = &n[1];
int *p3 = &n[0];
int *p4 = NULL;
printf("等価演算子 真:1 偽:0\n\n");
printf("1 (int) == 2 (int) --- i1 == i2 --> %d\n", i1 == i2);
printf("1 (int) == 1 (int) --- i1 == i3 --> %d\n", i1 == i3);
printf("1.0 (double) == 2.0 (double) --- d1 == d2 --> %d\n", d1 == d2);
printf("1.0 (double) == 1.0 (double) --- d1 == d3 --> %d\n", d1 == d3);
printf("1 (int) == 2.0 (double) --- i1 == d2 --> %d\n", i1 == d2);
printf("1 (int) == 1.0 (double) --- i1 == d1 --> %d\n", i1 == d3);
printf("&n[0] (int *) == &n[1] (int *) --- p1 == p2 --> %d\n", p1 == p2);
printf("&n[0] (int *) == &n[0] (int *) --- p1 == p3 --> %d\n", p1 == p3);
printf("&n[0] (int *) == NULL --- p1 == NULL --> %d\n", p1 == NULL);
printf("NULL == NULL --- p4 == NULL --> %d\n\n", p4 == NULL);
printf("1 (int) != 2 (int) --- i1 != i2 --> %d\n", i1 != i2);
printf("1 (int) != 1 (int) --- i1 != i3 --> %d\n", i1 != i3);
printf("1.0 (double) != 2.0 (double) --- d1 != d2 --> %d\n", d1 != d2);
printf("1.0 (double) != 1.0 (double) --- d1 != d3 --> %d\n", d1 != d3);
printf("1 (int) != 2.0 (double) --- i1 != d2 --> %d\n", i1 != d2);
printf("1 (int) != 1.0 (double) --- i1 != d1 --> %d\n", i1 != d3);
printf("&n[0] (int *) != &n[1] (int *) --- p1 != p2 --> %d\n", p1 != p2);
printf("&n[0] (int *) != &n[0] (int *) --- p1 != p3 --> %d\n", p1 != p3);
printf("&n[0] (int *) != NULL --- p1 != NULL --> %d\n", p1 != NULL);
printf("NULL != NULL --- p4 != NULL --> %d\n\n", p4 != NULL);
return EXIT_SUCCESS;
}
実行結果
$ gcc -Wall sample.c
$ ./a.out
等価演算子 真:1 偽:0
1 (int) == 2 (int) --- i1 == i2 --> 0
1 (int) == 1 (int) --- i1 == i3 --> 1
1.0 (double) == 2.0 (double) --- d1 == d2 --> 0
1.0 (double) == 1.0 (double) --- d1 == d3 --> 1
1 (int) == 2.0 (double) --- i1 == d2 --> 0
1 (int) == 1.0 (double) --- i1 == d1 --> 1
&n[0] (int *) == &n[1] (int *) --- p1 == p2 --> 0
&n[0] (int *) == &n[0] (int *) --- p1 == p3 --> 1
&n[0] (int *) == NULL --- p1 == NULL --> 0
NULL == NULL --- p4 == NULL --> 1
1 (int) != 2 (int) --- i1 != i2 --> 1
1 (int) != 1 (int) --- i1 != i3 --> 0
1.0 (double) != 2.0 (double) --- d1 != d2 --> 1
1.0 (double) != 1.0 (double) --- d1 != d3 --> 0
1 (int) != 2.0 (double) --- i1 != d2 --> 1
1 (int) != 1.0 (double) --- i1 != d1 --> 0
&n[0] (int *) != &n[1] (int *) --- p1 != p2 --> 1
&n[0] (int *) != &n[0] (int *) --- p1 != p3 --> 0
&n[0] (int *) != NULL --- p1 != NULL --> 1
NULL != NULL --- p4 != NULL --> 0
実行環境
GNU bash, version 5.1.16
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39
GCC-12.2.0
GNU C Library 2.36
GNU Binutils 2.39
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。