C言語って何? 標準関数を使ってみる
それでは、その「標準関数」です。
<assert.h>
assert
<complex.h>
cacos
cacosf
cacosl
casin
casinf
casinl
catan
catanf
catanl
ccos
ccosf
ccosl
csin
csinf
csinl
ctan
ctanf
ctanl
cacosh
cacoshf
cacoshl
casinh
casinhf
casinhl
catanh
catanhf
catanhl
ccosh
ccoshf
ccoshl
csinh
csinhf
csinhl
ctanh
ctanhf
ctanhl
cexp
cexpf
cexpl
clog
clogf
clogl
cabs
cabsf
cabsl
cpow
cpowf
cpowl
csqrt
csqrtf
csqrtl
carg
cargf
cargl
cimag
cimagf
cimagl
conj
conjf
conjl
cproj
cprojf
cprojl
creal
crealf
creall
<ctype.h>
isalnum
isalpha
isblank
iscntrl
isdigit
isgraph
islower
isprint
ispunct
isspace
isupper
isxdigit
tolower
toupper
<fenv.h>
feclearexcept
fegetexceptflag
feraiseexcept
fesetexceptflag
fetestexcept
fegetround
fesetround
fegetenv
feholdexcept
fesetenv
feupdateenv
<inttypes.h>
imaxabs
imaxdiv
strtoimax
strtoumax
wcstoimax
wcstoumax
<locale.h>
setlocale
localeconv
<math.h>
fpclassify
isfinite
isinf
isnan
isnormal
signbit
acos
acosf
acosl
asin
asinf
asinl
atan
atanf
atanl
atan2
atan2f
atan2l
cos
cosf
cosl
sin
sinf
sinl
tan
tanf
tanl
acosh
acoshf
acoshl
asinh
asinhf
asinhl
atanh
atanhf
atanhl
cosh
coshf
coshl
sinh
sinhf
sinhl
tanh
tanhf
tanhl
exp
expf
expl
exp2
exp2f
exp2l
expm1
expm1f
expm1l
frexp
frexpf
frexpl
ilogb
ilogbf
ilogbl
ldexp
ldexpf
ldexpl
log
logf
logl
log10
log10f
log10l
log1p
log1pf
log1pl
log2
log2f
log2l
logb
logbf
logbl
modf
modff
modfl
scalbn
scalbnf
scalbnl
scalbln
scalblnf
scalblnl
cbrt
cbrtf
cbrtl
fabs
fabsf
fabsl
hypot
hypotf
hypotl
pow
powf
powl
sqrt
sqrtf
sqrtl
erf
erff
erfl
erfc
erfcf
erfcl
lgamma
lgammaf
lgammal
tgamma
tgammaf
tgammal
ceil
ceilf
ceill
floor
floorf
floorl
nearbyint
nearbyintf
nearbyintl
rint
rintf
rintl
lrint
lrintf
lrintl
llrint
llrintf
llrintl
round
roundf
roundl
lround
lroundf
lroundl
llround
llroundf
llroundl
trunc
truncf
truncl
fmod
fmodf
fmodl
remainder
remainderf
remainderl
remquo
remquof
remquol
copysign
copysignf
copysignl
nan
nanf
nanl
nextafter
nextafterf
nextafterl
nexttoward
nexttowardf
nexttowardl
fdim
fdimf
fdiml
fmax
fmaxf
fmaxl
fmin
fminf
fminl
fma
fmaf
fmal
isgreater
isgreaterequal
isless
islessequal
islessgreater
isunordered
<setjmp.h>
setjmp
longjmp
<signal.h>
signal
raise
<stdarg.h>
va_arg
va_copy
va_end
va_start
<stdio.h>
remove
rename
tmpfile
tmpnam
fclose
fflush
fopen
freopen
setbuf
setvbuf
fprintf
fscanf
printf
scanf
snprintf
sprintf
sscanf
vfprintf
vfscanf
vprintf
vscanf
vsnprintf
vsprintf
vsscanf
fgetc
fgets
fputc
fputs
getc
getchar
gets
putc
putchar
puts
ungetc
fread
fwrite
fgetpos
fseek
fsetpos
ftell
rewind
clearerr
feof
ferror
perror
<stdlib.h>
atof
atoi
atol
atoll
strtod
strtof
strtold
strtol
strtoll
strtoul
strtoull
rand
srand
calloc
free
malloc
realloc
abort
atexit
exit
_Exit
getenv
system
bsearch
qsort
abs
labs
llabs
div
ldiv
lldiv
mblen
mbtowc
wctomb
mbstowcs
wcstombs
<string.h>
memcpy
memmove
strcpy
strncpy
strcat
strncat
memcmp
strcmp
strcoll
strncmp
strxfrm
memchr
strchr
strcspn
strpbrk
strrchr
strspn
strstr
strtok
memset
strerror
strlen
wcscmp
wcscoll
wcsncmp
wcsxfrm
wmemcmp
wcschr
wcscspn
wcspbrk
wcsrchr
wcsspn
wcsstr
wcstok
wmemchr
wcslen
wmemset
wcsftime
btowc
wctob
mbsinit
mbrlen
mbrtowc
wcrtomb
mbsrtowcs
wcsrtombs
<wctype.h>
iswalnum
iswalpha
iswblank
iswcntrl
iswdigit
iswgraph
iswlower
iswprint
iswpunct
iswspace
iswupper
iswxdigit
iswctype
wctype
towlower
towupper
towctrans
wctrans
え?
こんなに?
いつの間に、これだけ増えたのか。
ちなみに、組み込みソフトウェアではほとんど(私の場合は全く)使わない。
標準関数はコンパイラが提供しているわけですが、どうしても品質に確信が持てない。
例えば、「malloc」一つにしてもそうで、継続して使用してフラグメントの問題が発生しないかどうかが気になります。
入出力はリソースを多く消費するのでこれも安易に使えない。組み込みの場合は標準の入出力を持っていないことも少なくないので、使えない。
列挙していて気になったのは「<complex.h>」。
複素数の演算なんてあったっけ。
「<math.h>」もそう。
こんなにあったかなぁ。
関数の数が多くなったもう一つの理由は、多重定義ができないことのようです。
math関係にも、データの型違いというものも多い。
いずれにしても、これは覚える必要はありません。
必要な時に調べて使えればよろし。
「使えれば」というようにするには勉強しておかなきゃいけないんじゃないか。
もっともですが、標準関数はコンパイラによって若干の差異があります。せっかく勉強したけど使っているコンパイラが対応していないという可能性もあります。ですので、標準関数は使う時に、使っているコンパイラで調べましょう。
第一、プログラミング能力はそこにはありません。
あまりの数の多さに右往左往しましたが、本題に戻ります。
前回は「1+1」だけを実行して終わったのでした。
「1+1」を実行するだけで結果さえ見れず、何をしてるんだか、さっぱりわからないプログラムです。
ですので、せめて結果を出力したい。
そこで標準関数です。
入出力は「<stdio.h>」にあります。
「std」は「Standard」(標準)の略。
「io」は「InputOutput」(入力出力)の略。
「printf」を使います。
#include <stdio.h>
int main()
{
int x = 1 + 1;
printf("1 + 1 = %d\n", x);
return 0;
}
実行してみます。
$ ./a.out
1 + 1 = 2
$
「1 + 1 = 2」と、結果が出力されました。
ここまでくると、入力もほしくなりますよね。
引数にするという方法もあるけど。
「scanf」を使ってみます。
#include <stdio.h>
int main()
{
int a;
int b;
int x;
printf("number1? --->");
scanf("%d", &a);
printf("number2? --->");
scanf("%d", &b);
x = a + b;
printf("%d + %d = %d\n", a, b, x);
return 0;
}
実行
$ ./a.out
number1? --->1
number2? --->1
1 + 1 = 2
$ ./a.out
number1? --->542764
number2? --->96284
542764 + 96284 = 639048
$
さて。
ここで使った「標準関数」は2つです。
scanf
printf
この2つも含めて、標準関数というのは予約語とは違います。標準関数は「予約語を駆使して作られた関数の一つ」に過ぎないのです。
予約語ではないので、同じシンボルを使うこともできます。だから「私だけのprintf」を作ることができます。ただ、もちろん、標準関数と同じシンボルをむやみに使っても混乱します。それに移植性も低下する。賛成する人は一人もいません。
いずれにしても、予約語と標準関数は明確に区別しましょう。どちらもC言語の規約ですが、レベルが異なります。
さて。
このプログラム。
もう少し続けてみましょうか。
一回しか計算してくれないのは面倒ですよね。
長くなりましたので次回に。
次の記事→ C言語 足し算プログラム改善