「C言語/標準ライブラリ/stdlib.h」の版間の差分

削除された内容 追加された内容
編集の要約なし
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
s/source/syntaxhighlight/g, +aligned_alloc、「例」のコードに、領域確保に失敗したのに、メッセージだけ出しそのままnullptrで処理を続けるバグ多数。
タグ: 2017年版ソースエディター
24 行
|-
!記憶域管理関数!!
|-
|[[#aligned_alloc関数|void *aligned_alloc(size_t alignment, size_t size);]]||指定したアライメントでメモリを確保する<ref name="aligned_alloc-c11">ISO/IEC 9899:2011(C11)で追加されました。</ref>。
|-
|[[#calloc関数|void *calloc(size_t nmemb, size_t size);]]||配列の領域を割り付ける。
106 ⟶ 108行目:
<ref>『JISX3010:2003』p.221「7.20.1.1 atof関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
double atof(const char *nptr);
</syntaxhighlight>
</source>
*引数
:nptr 文字列
117 ⟶ 119行目:
:atof関数とは、nptrが指す文字列の最初の部分を、double型の表現に変換する関数である。
:stof関数は、エラーが発生したときの動作を除けば、
<sourcesyntaxhighlight lang=c>
strtod(nptr, (char **)NULL)
</syntaxhighlight>
</source>
と等価である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
134 ⟶ 136行目:
printf("dの値:%.2f\n", d);
}
</syntaxhighlight>
</source>
=== atoi, atol及びatoll関数 ===
<ref>『JISX3010:2003』p.221「7.20.1.2 atoi, atol及びatoll関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int atoi(const char *nptr);
long int atol(const char *nptr);
long long int atoll(const char *nptr);
</syntaxhighlight>
</source>
*引数
:nptr 文字列
153 ⟶ 155行目:
:atoll関数とは、nptrが指す文字列の最初の部分を、long long int型の表現に変換する関数である。
これらの関数は、エラーが発生したときの動作を除けば、
<sourcesyntaxhighlight lang=c>
(int)strtol(nptr, (char **)NULL, 10)
strtol(nptr, (char **)NULL, 10)
strtoll(nptr, (char **)NULL, 10)
</syntaxhighlight>
</source>
とそれぞれ等価である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
172 ⟶ 174行目:
printf("iの値:%d\n", i);
}
</syntaxhighlight>
</source>
=== strtod, strtof及びstrtold関数 ===
<ref>『JISX3010:2003』p.222「7.20.1.3 strtod, strtof及びstrtold関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
double strtod(const char * restrict nptr, char ** restrict endptr);
float strtof(const char * restrict nptr, char ** restrict endptr);
long double strtold(const char * restrict nptr, char ** restrict endptr);
</syntaxhighlight>
</source>
*引数
:nptr 入力文字列
193 ⟶ 195行目:
:strtold関数とは、nptrが指す文字列の最初の部分を、long double型の表現に変換する関数である。
:これらの関数は、入力文字列を次の3つの部分に分割する。
<sourcesyntaxhighlight lang=c>
[空白類文字の並び][変換対象列][末尾の文字列]
</syntaxhighlight>
</source>
:空白類文字の並びは、isspace関数で規定される。
:変換対象列は、浮動小数点定数と同様の形式、又は無限大(INF及びINFINITY)若しくはNaNである。
202 ⟶ 204行目:
:endptrが空ポインタでなければ、末尾の文字列へのポインタをendptrが指すオブジェクトに格納する。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
216 ⟶ 218行目:
printf("endptrの値:%s\n", endptr);
}
</syntaxhighlight>
</source>
=== strtol, strtoll, strtoul及びstrtoull関数 ===
<ref>『JISX3010:2003』p.223「7.20.1.4 strtol, strtoll, strtoul及びstrtoull関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
long int strtol(const char * restrict nptr, char ** restrict endptr, int base);
226 ⟶ 228行目:
unsigned long int strtoul(const char * restrict nptr, char ** restrict endptr, int base);
unsigned long long int strtoull(const char * restrict nptr, char ** restrict endptr, int base);
</syntaxhighlight>
</source>
*引数
:nptr 入力文字列
240 ⟶ 242行目:
:strtoull関数とは、nptrが指す文字列の最初の部分を、baseで指定した基数で、unsigned long long int型の表現に変換する。
:これらの関数は、入力文字列を次の3つの部分に分割する。
<sourcesyntaxhighlight lang=c>
[空白類文字の並び][変換対象列][末尾の文字列]
</syntaxhighlight>
</source>
:空白類文字の並びは、isspace関数で規定される。
:変換対象列は、baseの値で決まる基数によって表現される整数と同様の形式である。
249 ⟶ 251行目:
:endptrが空ポインタでなければ、末尾の文字列へのポインタをendptrが指すオブジェクトに格納する。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
263 ⟶ 265行目:
printf("endptrの値:%s\n", endptr);
}
</syntaxhighlight>
</source>
 
== 疑似乱数列生成関数 ==
270 ⟶ 272行目:
<ref>『JISX3010:2003』p.225「7.20.2.1 rand関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int rand(void);
</syntaxhighlight>
</source>
*引数
:なし
281 ⟶ 283行目:
:rand関数とは、0以上RAND_MAX以下の範囲の疑似乱数整数列を計算する関数である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
295 ⟶ 297行目:
printf("iの値:%d\n", i);
}
</syntaxhighlight>
</source>
=== srand関数 ===
<ref>『JISX3010:2003』p.225「7.20.2.2 srand関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void srand(unsigned int seed);
</syntaxhighlight>
</source>
*引数
:seed 疑似乱数列の種
330 ⟶ 332行目:
 
 
aligned_allocもcallocもmallocも、メモリ領域の占有に成功した場合、返却値として、占有に成功したメモリ領域の先頭アドレスを返却する。占有に失敗した場合、空ポインタを返却する。
 
=== aligned_alloc関数 ===
aligned_alloc関数は、ISO/IEC 9899:2011(C11)で追加されました<ref>{{cite book | url=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf | title=ISO/IEC 9899:201x Committee Draft — April 12, 2011 N1570 | at=p.347, § 7.22.3.1 ''The aligned_alloc function''}}</ref>。
; 形式
: <syntaxhighlight lang=c>
#include <stdlib.h>
void *aligned_alloc(size_t alignment, size_t size);
</syntaxhighlight>
; 引数
: alignment アライメント値<ref>割り当てる型のアライメントは処理系によるので、を_Alignof()演算子で得た値を使うのが確実です。</ref>
: size バイト数、引数 alignment の倍数である必要があります。
; 返却値
: 割り付けられた領域の先頭へのポインタ。領域の割り付けができなかったときは、空ポインタ。
; 機能
: aligned_alloc関数は、指定したアライメント alignment で size 個のメモリを確保します。
; 例
: <syntaxhighlight lang=c>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
 
int main(void)
{
struct Point {
long double x, y;
};
struct Point *p;
const int size = 10;
 
if ((p = (struct Point *)aligned_alloc(_Alignof(struct Point), size)) == NULL) {
puts(strerror(errno));
exit(1);
}
 
printf("p = %p\n", p);
for (int i = 0; i < size; i++)
printf("%i: x = %Lf, y = %Lf\n", i, p[i].x, p[i].y);
free(p);
if ((p = (struct Point *)aligned_alloc(65536, ULONG_MAX)) == NULL) {
puts(strerror(errno));
exit(1);
}
printf("p = %p\n", p);
for (int i = 0; i < size; i++)
printf("%i: x = %Lf, y = %Lf\n", i, p[i].x, p[i].y);
}
</syntaxhighlight>
; 結果
: <syntaxhighlight lang=text>
p = 0x800a09000
0: x = 0.000000, y = 0.000000
1: x = 0.000000, y = 0.000000
2: x = 0.000000, y = 0.000000
3: x = 0.000000, y = 0.000000
4: x = 0.000000, y = 0.000000
5: x = 0.000000, y = 0.000000
6: x = 0.000000, y = 0.000000
7: x = 0.000000, y = 0.000000
8: x = 0.000000, y = 0.000000
9: x = 0.000000, y = 0.000000
Cannot allocate memory
</syntaxhighlight>
 
=== calloc関数 ===
<ref>『JISX3010:2003』p.226「7.20.3.1 calloc関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
</syntaxhighlight>
</source>
*引数
:nmenb 個数
349 ⟶ 414行目:
:その領域のすべてのビットは、0で初期化する。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
360 ⟶ 425行目:
if((p=(int *)calloc(nmemb, sizeof(int)))==NULL){
printf("領域の割り付けができませんでした。\n");
exit(1);
}
 
368 ⟶ 434行目:
free(p);
}
</syntaxhighlight>
</source>
 
=== free関数 ===
<ref>『JISX3010:2003』p.226「7.20.3.2 free関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void free(void *ptr);
</syntaxhighlight>
</source>
*引数
:ptr
390 ⟶ 457行目:
<ref>『JISX3010:2003』p.226「7.20.3.3 malloc関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void *malloc(size_t size);
</syntaxhighlight>
</source>
*引数
:size サイズ
402 ⟶ 469行目:
:割り付けられたオブジェクトの値は不定である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
413 ⟶ 480行目:
if((p=(int *)malloc(sizeof(int)*size))==NULL){
printf("領域の割り付けができませんでした。\n");
exit(1);
}
 
424 ⟶ 492行目:
free(p);
}
</syntaxhighlight>
</source>
=== realloc関数 ===
<ref>『JISX3010:2003』p.226「7.20.3.4 realloc関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
</syntaxhighlight>
</source>
*引数
:ptr
446 ⟶ 514行目:
:新しいオブジェクトに対する記憶域の割り付けができなかった場合、古いオブジェクトは解放されずその値は変化しない。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
457 ⟶ 525行目:
if((p=(int *)malloc(sizeof(int)*size))==NULL){
printf("領域の割り付けができませんでした。\n");
exit(1);
}
for(i=0; i<size; ++i)
467 ⟶ 536行目:
if((p=(int *)realloc(p, sizeof(int)*size))==NULL){
printf("領域の割り付けができませんでした。\n");
exit(1);
}
for(i=10; i<size; ++i)
476 ⟶ 546行目:
free(p);
}
</syntaxhighlight>
</source>
 
== 環境に関連する関数 ==
483 ⟶ 553行目:
<ref>『JISX3010:2003』p.227「7.20.4.1 abort関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void abort(void);
</syntaxhighlight>
</source>
*引数
:なし
500 ⟶ 570行目:
 
*例
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
 
507 ⟶ 577行目:
abort();
}
</syntaxhighlight>
</source>
=== atexit関数 ===
<ref>『JISX3010:2003』p.227「7.20.4.2 atexit関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int atexit(void (*func)(void));
</syntaxhighlight>
</source>
*引数
:func 関数
523 ⟶ 593行目:
:少なくとも32この関数の登録がサポートされる。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
538 ⟶ 608行目:
printf("function関数が呼ばれました。\n");
}
</syntaxhighlight>
</source>
=== exit関数 ===
<ref>『JISX3010:2003』p.227「7.20.4.3 exit関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void exit(int status);
</syntaxhighlight>
</source>
*引数
:status 状態
558 ⟶ 628行目:
#制御をホスト環境に戻す。statusの値が0又はEXIT_SUCCESSの場合、成功終了状態を処理系定義の形式で返す。statusの値がEXIT_FAILUREの場合、失敗終了状態を処理系定義の形式で返す。それ以外の場合、返される状態は処理系定義とする。
*例
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
 
565 ⟶ 635行目:
exit(0);
}
</syntaxhighlight>
</source>
=== _Exit関数 ===
<ref>『JISX3010:2003』p.228「7.20.4.4 _Exit関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void _Exit(int status);
</syntaxhighlight>
</source>
*引数
:status 状態
587 ⟶ 657行目:
 
*例
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
 
594 ⟶ 664行目:
_Exit(0);
}
</syntaxhighlight>
</source>
=== getenv関数 ===
<ref>『JISX3010:2003』p.228「7.20.4.5 getenv関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
char *getenv(const char *name);
</syntaxhighlight>
</source>
*引数
:name 文字列
609 ⟶ 679行目:
:getenv関数とは、ホスト環境が提供する環境の並びの中で、nameが指す文字列と一致する文字列を探索する関数である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
620 ⟶ 690行目:
printf("osの値:%s\n", os);
}
</syntaxhighlight>
</source>
=== system関数 ===
<ref>『JISX3010:2003』p.228「7.20.4.6 system関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int system(const char *string);
</syntaxhighlight>
</source>
*引数
:string 空ポインタ、又はコマンド。
637 ⟶ 707行目:
:stringが空ポインタでないとき、system関数は、stringが指す文字列をコマンドプロセッサへ、その文字列を実行させるために渡す。
*例
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
 
644 ⟶ 714行目:
system("dir");//コマンドプロンプトを用いてファイルを一覧表示する。
}
</syntaxhighlight>
</source>
 
== 探索及び整列ユーティリティ ==
651 ⟶ 721行目:
<ref>『JISX3010:2003』p.229「7.20.5.1 bsearch関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
</syntaxhighlight>
</source>
*引数
:key オブジェクト
672 ⟶ 742行目:
:配列は、keyオブジェクトと比較して、小さい要素だけの部分、等しい要素だけの部分及び大きい要素だけの部分から構成され、これら3つの部分が、この順序で存在しなければならない。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
693 ⟶ 763行目:
return *a-*b;
}
</syntaxhighlight>
</source>
=== qsort関数 ===
<ref>『JISX3010:2003』p.230「7.20.5.2 qsort関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
</syntaxhighlight>
</source>
*引数
:base オブジェクト
718 ⟶ 788行目:
:二つの要素が等しいとき、整列された配列内でのそれらの順序は未規定である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
740 ⟶ 810行目:
return *a-*b;
}
</syntaxhighlight>
</source>
 
== 整数算術関数 ==
747 ⟶ 817行目:
<ref>『JISX3010:2003』p.230「7.20.6.1 abs, labs, 及びllabs関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int abs(int j);
long int labs(long int j);
long long int llabs(long long int j);
</syntaxhighlight>
</source>
*引数
:j 整数
762 ⟶ 832行目:
:llabs関数とは、整数jの絶対値を計算する関数である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
774 ⟶ 844行目:
printf("iの値:%d\n", i);
}
</syntaxhighlight>
</source>
=== div, ldiv 及びlldiv関数 ===
<ref>『JISX3010:2003』p.230「7.20.6.2 div, ldiv, 及びlldiv関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int demon);
lldiv_t lldiv(long long int numer, long long int denom);
</syntaxhighlight>
</source>
*引数
:numer 割られる数
794 ⟶ 864行目:
:lldiv関数は、一回の呼び出しでnumer/denom(商)及びnumer%denom(剰余)の両方を計算する関数である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
806 ⟶ 876行目:
printf("10/3は%d。\n10%%3は%d。", dt.quot, dt.rem);
}
</syntaxhighlight>
</source>
 
== 多バイト文字・ワイド文字変換関数 ==
814 ⟶ 884行目:
<ref>『JISX3010:2003』p.231「7.20.7.1 mblen関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int mblen(const char *s, size_t n);
</syntaxhighlight>
</source>
*引数
:s 多バイト文字
827 ⟶ 897行目:
:mblen関数とは、sが空ポインタでないとき、sが指す多バイト文字を構成するバイト数を決定し、返却する関数である。
:mbtowc関数の変換状態が影響を受けないことを除き、
<sourcesyntaxhighlight lang=c>
mbtowc((wchar_t *)0, s, n)
</syntaxhighlight>
</source>
:と等価である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
848 ⟶ 918行目:
printf("%sのバイト数は%d。\n", s, l);
}
</syntaxhighlight>
</source>
=== mbtowc関数 ===
<ref>『JISX3010:2003』p.231「7.20.7.2 mbtowc関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int mbtowc(wchar_t * restrict pwc, char * restrict s, size_t n);
</syntaxhighlight>
</source>
*引数
:pwc 値を格納するオブジェクト
870 ⟶ 940行目:
#次に、pwcが空ポインタでない場合、pwcが指すオブジェクトにこの値を格納する関数である。対応するワイド文字がナルワイド文字である場合、この関数の状態は初期変換状態になる。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
888 ⟶ 958行目:
wprintf(L"wcの値:%c\n", wc);
}
</syntaxhighlight>
</source>
=== wctomb関数 ===
<ref>『JISX3010:2003』p.232「7.20.7.3 wctomb関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
int wctomb(char *s, wchar_t wc);
</syntaxhighlight>
</source>
*引数
:s 値を格納する配列
908 ⟶ 978行目:
#wcがナルワイド文字である場合、初期シフト状態に戻るために必要なシフトシーケンスがあればそれを格納し、さらになる文字を格納する。この場合、この関数の状態は初期変換状態になる。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
926 ⟶ 996行目:
printf("mbの値:%s\n", mb);
}
</syntaxhighlight>
</source>
 
== 多バイト文字列・ワイド文字列変換関数 ==
934 ⟶ 1,004行目:
<ref>『JISX3010:2003』p.232「7.20.8.1 mbstowcs関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n);
</syntaxhighlight>
</source>
*引数
:pwcs 変換したワイド文字列を格納する配列
954 ⟶ 1,024行目:
:領域の重なり合うオブジェクト間でコピーが行われるとき、その動作は未定義である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
972 ⟶ 1,042行目:
wprintf(L"wcsの値:%s\n", wcs);
}
</syntaxhighlight>
</source>
=== wcstombs関数 ===
<ref>『JISX3010:2003』p.233「7.20.8.2 wcstombs関数」</ref>
*形式
<sourcesyntaxhighlight lang=c>
#include <stdlib.h>
size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n);
</syntaxhighlight>
</source>
*引数
:s 変換した多バイト文字列を格納する配列
995 ⟶ 1,065行目:
:領域の重なり合うオブジェクト間でコピーが行われるとき、その動作は未定義である。
*例
<sourcesyntaxhighlight lang=c>
#include <stdio.h>
#include <stdlib.h>
1,013 ⟶ 1,083行目:
printf("mbsの値:%s\n", mbs);
}
</syntaxhighlight>
</source>
 
== 脚注 ==