LoginSignup
20
13

More than 3 years have passed since last update.

汎用ポインタ(void *)の使い方

Last updated at Posted at 2020-06-23

汎用ポインタ(void *)とは

ポインタ(*)型でのみ使用できる、void型の変数のこと。
CやC++などの標準ライブラリで見られる。

汎用という単語の通り、あらゆるポインタ型に変換可能。ポインタ型であればどのような型でも受け取ることができる。

char*型やint*型と異なり対象のサイズがないので用途に応じてキャストして使う。

C 標準ライブラリでの使用例

1. memcpy

srcの先頭からlenバイト分をdestへコピーする関数。
引数のdestとsrcはvoid*型であり、関数内でchar*型にキャストされる。

memcpy.c
void *memcpy(void *dest, const void *src, size_t len)
{
    char *d_cpy;
    const char *s_cpy;

    d_cpy = (char *)dest; //char*型にキャスト
    s_cpy = (const char*)src; //const char*型にキャスト
    while (len--)
        *d_cpy++ = *s_cpy++;
    return (dest);
}

2. memchr

srcの先頭からlenバイト分検索し、文字chがある位置のポインタを返す関数。
引数のsrcがconst void*型であり、関数内でconst char*型にキャストされる。

※const: 中身を書き換えられたくない値に対して書き込み禁止とする修飾子

memchr.c
void *memchr(const void *src, int ch, size_t len)
{
    const char *src_cpy;
    int        count;

    src_cpy = (const char *)src; //const char*型にキャスト
    count = 0;
    while (len--)
    {
        if (src_cpy[count] == ch)
            return ((void *)&src_cpy[count]);
        count++;
    }
    return (NULL);
}

C標準ライブラリのmem-関数では、メモリそのものを処理対象とするため、あらゆる型に対応できるよう汎用ポインタ(void *)型が用いられる。

その特性上、mem-関数は

  • strcpy関数のように戻り値のポインタの終端にnull('¥0')を付与することはない(返すのは文字列ではなくメモリ領域だから)
  • srcの途中にnull('¥0')が含まれていてもコピーや検索を中断しない。

汎用ポインタ(void *)のメリット

  • あらゆる型を出入力に使うことができる
  • ポインタの参照先の型が見えないようにすることでメモリアクセスを制限する
20
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
13