メモリの操作

バッファ内データの検索

memchr

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/*
  string.h [memchr]
  
  書式: void* memchr(const void *s, int c, size_t n)
  機能: バッファ内のデータを検索
  引数: const void *s: 検索対象となるバッファ
        int c: 検索するデータ
	size_t n: 検索バイト数
  戻り値: 検索データ (c) を最初に発見した位置のポインタを返し,
          発見できなかったは, NULL を返す.
*/

/*
  '\0' と  '\t' などがあっても検索できる
*/

#include <stdio.h>
#include <string.h>

int main(void){
  char c = 'L';
  char *s = "ABCDEFG\0\tHIJKLMN";
  char *ret;

  /* 20 は *s の文字列の長さ以上であること */
  ret = (char *)memchr(s, c, 20);
  if( ret != NULL)
    printf("%c を %d 番目に発見した\n", c, (int)(ret-s));
  else
    printf("%c を発見できない\n", c);
  
  return 0;
}

memchr.c の実行結果は:

[cactus:~/code_c/refer]% ./memchr
L を 13 番目に発見した

バッファのデータ比較

memcmp.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/*
  string.h [memcmp]
  
  書式: int memcmp(const void *s1, const void *s2, size_t n)
  機能: バッファ同士のデータを比較
  引数: const void *s1: 比較するバッファ
        const void *s2: 比較するバッファ
	size_t n: 比較するバイト数
  戻り値:
          s1 < s2: 負の値
	  s1 = s2: 0
	  s1 > s2: 正の値
*/

#include <stdio.h>
#include <string.h>

int main(void){
  int s1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  int s2[] = {1, 2, 3, 4, 5, 9, 8, 7, 6};
  int ret;

  ret = memcmp(s1, s2, sizeof(int) * 5);
  printf("比較結果: %d\n", ret);

  ret = memcmp(s1, s2, sizeof(int) * 6);
  printf("比較結果: %d\n", ret);
  
  return 0;
}

memcmp.c の実行結果は:

[cactus:~/code_c/refer]% ./memcmp
比較結果: 0
比較結果: -3

バッファのコピー

memcpy.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
  string.h [memcpy]
  
  書式: void* memcpy(void *s1, const void *s2, size_t n)
  機能: バッファのコピー
  引数: void *s1: コピー先となるバッファ
        const void *s2: コピー元となるバッファ
	size_t n: コピーするバイト数
  戻り値: コピー先バッファ (s1) を返す
*/

/*
  strncpy() と似ているが, [\0] は追加されない
*/

#include <stdio.h>
#include <string.h>

int main(void){
  int s1[3];
  int s2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

  memcpy(s1, s2, sizeof(int) * 3);
  printf("%d, %d, %d\n", s1[0], s1[1], s1[2]);
  
  return 0;
}

memcpy.c の実行結果は:

[cactus:~/code_c/refer]% ./memcpy
1, 2, 3

バッファを指定した値で設定

memset.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
  string.h [memset]
  
  書式: void* memset(void *s, int c, size_t n)
  機能: バッファを指定した値で設定
  引数: void *s: 設定対象のバッファ
        int c: 設定する値
	size_t n: 設定バイト数
  戻り値: 設定対象のバッファ (s) を返す.
*/

/*
  memset() は, 構造体や配列の初期化に使われることが多い.
*/

#include <stdio.h>
#include <string.h>

int main(void){
  int s[10] = {1, 2};
  int i;

  printf("初期化の状態\n");
  for(i = 0; i < 10; i++)
    printf("%d\n", s[i]);

  /* 配列を初期化する */
  memset(s, 0, sizeof(int) * 10);

  printf("初期化後の状態\n");
  for(i = 0; i < 10; i++)
    printf("%d\n", s[i]);

  return 0;
}

memset.c の実行結果は:

初期化の状態
1
2
0
0
0
0
0
0
0
0
初期化後の状態
0
0
0
0
0
0
0
0
0
0

バッファのコピー (移動)

memmove.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
  string.h [memmove]
  
  書式: void* memmove(void *s1, const void *s2, size_t n)
  機能: バッファのコピー (移動)
  引数: void *s1: コピー先となるバッファ
        const void *s2: コピー元となるバッファ
	size_t n: コピーするバイト数
  戻り値: コピー先バッファ (s1) を返す.
*/

#include <stdio.h>
#include <string.h>

int main(void){
  char s1[] = "1234567890";

  printf("コピー前: %s\n", s1);
  memmove(s1+3, s1, 3);
  printf("コピー後: %s\n", s1);

  return 0;
}
/*
  コピー先文字列の 4 番目 (index 3) に 3 文字コピーしている.
  メモリ領域が重複しているが問題ないわけ.
*/

memmove.c の実行結果は:

[cactus:~/code_c/refer]% ./memmove
コピー前: 1234567890
コピー後: 1231237890