mem_addr.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 | #include <stdio.h>
int main(void){
char str[] = "ABCDEFG";
printf("str[-3] = '%2c' [%p]\n" ,str[-3], str - 3);
printf("str[-2] = '%2c' [%p]\n" ,str[-2], str - 2);
printf("str[-1] = '%2c' [%p]\n" ,str[-1], str - 1);
printf("\n");
printf("str[ 0] = '%c' [%p]\n" ,str[0], str + 0);
printf("str[ 1] = '%c' [%p]\n" ,str[1], str + 1);
printf("str[ 2] = '%c' [%p]\n" ,str[2], str + 2);
printf("str[ 3] = '%c' [%p]\n" ,str[3], str + 3);
printf("str[ 4] = '%c' [%p]\n" ,str[4], str + 4);
printf("str[ 5] = '%c' [%p]\n" ,str[5], str + 5);
printf("str[ 6] = '%c' [%p]\n" ,str[6], str + 6);
printf("str[ 7] = '%2c' [%p]\n" ,str[7], str + 7);
printf("\n");
printf("str[ 8] = '%c' [%p]\n" ,str[8], str + 8);
printf("str[ 9] = '%c' [%p]\n" ,str[9], str + 9);
printf("str[10] = '%c' [%p]\n" ,str[10], str + 10);
return 0;
}
|
mem_addr.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./mem_addr
str[-3] = ' ' [0x7fff5fbff3cd]
str[-2] = ' ' [0x7fff5fbff3ce]
str[-1] = ' ' [0x7fff5fbff3cf]
str[ 0] = 'A' [0x7fff5fbff3d0]
str[ 1] = 'B' [0x7fff5fbff3d1]
str[ 2] = 'C' [0x7fff5fbff3d2]
str[ 3] = 'D' [0x7fff5fbff3d3]
str[ 4] = 'E' [0x7fff5fbff3d4]
str[ 5] = 'F' [0x7fff5fbff3d5]
str[ 6] = 'G' [0x7fff5fbff3d6]
str[ 7] = ' ' [0x7fff5fbff3d7]
str[ 8] = '?' [0x7fff5fbff3d8]
str[ 9] = 'a' [0x7fff5fbff3d9]
str[10] = '?' [0x7fff5fbff3da]
mem_addr2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h>
int main(void){
unsigned int m[5] = {3, 7, 10};
printf("m[0] = %2d [%p]\n", m[0], m + 0);
printf("m[1] = %2d [%p]\n", m[1], m + 1);
printf("m[2] = %2d [%p]\n", m[2], m + 2);
printf("m[3] = %2d [%p]\n", m[3], m + 3);
printf("m[4] = %2d [%p]\n", m[4], m + 4);
return 0;
}
|
mem_addr2.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./mem_addr2
m[0] = 3 [0x7fff5fbff3b0]
m[1] = 7 [0x7fff5fbff3b4]
m[2] = 10 [0x7fff5fbff3b8]
m[3] = 0 [0x7fff5fbff3bc]
m[4] = 0 [0x7fff5fbff3c0]
アドレスからそのメモリ箇所に記憶される値を参照することを [間接参照] (indirection) と言う. 間接参照するための演算子が [間接演算子]である
間接演算子 (Indirection Operator):
*オペランド
indirect.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h>
int main(void){
char str[] = "WTOPIA.";
printf("str[0] = '%c' [%p]\n", *(str), str+0);
printf("str[1] = '%c' [%p]\n", *(str+1), str+1);
printf("str[2] = '%c' [%p]\n", *(str+2), str+2);
printf("str[3] = '%c' [%p]\n", *(str+3), str+3);
printf("str[4] = '%c' [%p]\n", *(str+4), str+4);
printf("str[5] = '%c' [%p]\n", *(str+5), str+5);
printf("str[6] = '%c' [%p]\n", *(str+6), str+6);
printf("str[7] = '%2c' [%p]\n", *(str+7), str+7);
return 0;
}
|
indirect.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./indirect
str[0] = 'W' [0x7fff5fbff3d0]
str[1] = 'T' [0x7fff5fbff3d1]
str[2] = 'O' [0x7fff5fbff3d2]
str[3] = 'P' [0x7fff5fbff3d3]
str[4] = 'I' [0x7fff5fbff3d4]
str[5] = 'A' [0x7fff5fbff3d5]
str[6] = '.' [0x7fff5fbff3d6]
str[7] = ' ' [0x7fff5fbff3d7]
indirect2.c
1 2 3 4 5 6 7 8 9 10 11 12 | #include <stdio.h>
int main(void){
unsigned int m[5] = {3, 7, 10};
printf("m[0] = %2d [%p]\n", *(m+0), m+0);
printf("m[1] = %2d [%p]\n", *(m+1), m+1);
printf("m[2] = %2d [%p]\n", *(m+2), m+2);
printf("m[3] = %2d [%p]\n", *(m+3), m+3);
printf("m[4] = %2d [%p]\n", *(m+4), m+4);
return 0;
}
|
indirect2.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./indirect2
m[0] = 3 [0x7fff5fbff3b0]
m[1] = 7 [0x7fff5fbff3b4]
m[2] = 10 [0x7fff5fbff3b8]
m[3] = 0 [0x7fff5fbff3bc]
m[4] = 0 [0x7fff5fbff3c0]
pointer.c
1 2 3 4 5 6 7 8 9 | #include <stdio.h>
int main(void){
char str[] = "WTOPIA.";
char *p = str;
printf("str[0] = '%c' [%p]\n", *p, p);
return 0;
}
|
pointer.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./pointer
str[0] = 'W' [0x7fff5fbff3d0]
ptr_arith.c
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h>
int main(void){
char str[] = "WTOPIA.";
char *p;
for(p = str; *p != '\0'; p++)
// '\0' にしなくてはいけない
// '0' だったら知らない場所に指すかもしれない
printf("'%c' %x [%p]\n", *p, *p, p);
return 0;
}
|
ptr_arith.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_arith
'W' 57 [0x7fff5fbff3c0]
'T' 54 [0x7fff5fbff3c1]
'O' 4f [0x7fff5fbff3c2]
'P' 50 [0x7fff5fbff3c3]
'I' 49 [0x7fff5fbff3c4]
'A' 41 [0x7fff5fbff3c5]
'.' 2e [0x7fff5fbff3c6]
ptr_arith2.c
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h>
int main(void){
char str[] = "WTOPIA.";
char *p;
for(p = str; *p != '\0'; p++)
printf("str[%td] '%c' %x [%p]\n", p - str, *p, *p, p);
return 0;
}
|
ptr_arith2.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_arith2
str[0] 'W' 57 [0x7fff5fbff3c0]
str[1] 'T' 54 [0x7fff5fbff3c1]
str[2] 'O' 4f [0x7fff5fbff3c2]
str[3] 'P' 50 [0x7fff5fbff3c3]
str[4] 'I' 49 [0x7fff5fbff3c4]
str[5] 'A' 41 [0x7fff5fbff3c5]
str[6] '.' 2e [0x7fff5fbff3c6]
subscript.c
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h>
int main(void){
char str[] = "WTOPIA.";
int i;
for(i = 0; str[i] != '\0'; i++)
printf("str[%d] '%c' %x [%p]\n", i, *(str+i), *(str+i), str+i);
return 0;
}
|
subscript.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./subscript
str[0] 'W' 57 [0x7fff5fbff3c0]
str[1] 'T' 54 [0x7fff5fbff3c1]
str[2] 'O' 4f [0x7fff5fbff3c2]
str[3] 'P' 50 [0x7fff5fbff3c3]
str[4] 'I' 49 [0x7fff5fbff3c4]
str[5] 'A' 41 [0x7fff5fbff3c5]
str[6] '.' 2e [0x7fff5fbff3c6]
addr_opera.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <stdio.h>
int main(void){
int x = 2, y = 3;
int *p; // int *型変数 (int へのポインタ) の宣言
printf("x = %d [%p]\n", x ,&x);
printf("y = %d [%p]\n", y ,&y);
p = &x;
printf("p = %p\n", p);
*p = 10; // * は間接演算子
p = &y;
printf("P = %p\n", p);
*p = 10; // * は間接演算子
printf("x = %d\n", x);
printf("y = %d\n", y);
return 0;
}
|
addr_opera.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./addr_opera
x = 2 [0x7fff5fbff3cc]
y = 3 [0x7fff5fbff3c8]
p = 0x7fff5fbff3cc
P = 0x7fff5fbff3c8
x = 10
y = 10
null_ptr.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h>
int main(void){
char *p;
p = 0;
if(p == NULL)
printf("Yes! [%p]\n", p);
p = (void *)0;
if(p == NULL)
printf("Yes! [%p]\n", p);
if(!p)
printf("Yes! [%p]\n", p);
if(NULL == 0x00)
printf("Yes! [%p]\n", p);
return 0;
}
|
null_ptr.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./null_ptr
Yes! [0x0]
Yes! [0x0]
Yes! [0x0]
Yes! [0x0]
ptr_ptr.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h>
int main(void){
char x[] = "testing";
char *p;
char **z;
printf(" x = %p\n", x);
p = x;
printf(" p = %p, &p = %p\n", p, &p);
z = &p;
printf("*z = %p, z = %p\n", *z, z);
return 0;
}
|
ptr_ptr.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_ptr
x = 0x7fff5fbff3d0
p = 0x7fff5fbff3d0, &p = 0x7fff5fbff3c8
*z = 0x7fff5fbff3d0, z = 0x7fff5fbff3c8
ptr_array.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h>
int main(void){
char *x[10] = {
"char",
"short",
"int",
"long",
"float",
"double"
};
char *p;
char **z;
for(p = *x; *p != '\0'; p++)
printf("%c\t(%d)\t[%p]\n", *p, *p, p);
for(z = x; *z != NULL; z++)
printf("%s\t[%p]\n", *z, *z);
return 0;
}
|
ptr_array.c の実行結果は:
c (99) [0x100000efa]
h (104) [0x100000efb]
a (97) [0x100000efc]
r (114) [0x100000efd]
char [0x100000efa]
short [0x100000eff]
int [0x100000f05]
long [0x100000f09]
float [0x100000f0e]
double [0x100000f14]
ptr_func.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <stdio.h>
void f(int *);
int main(void){
int x = 2, y = 3;
f(&x);
f(&y);
printf("x = %d\n", x);
printf("y = %d\n", y);
return 0;
}
void f(int *p){ // int *型変数 (int へのポインタ)
*p = 10; // * は間接演算子
}
|
ptr_func.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_func
x = 10
y = 10
func.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <stdio.h>
void f(int);
int main(void){
int x = 2;
f(x);
printf("(3) x = %d\n", x);
return 0;
}
void f(int s){
printf("(1) s = %d\n", s);
s = 10;
printf("(2) s = %d\n", s);
}
|
func.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./func
(1) s = 2
(2) s = 10
(3) x = 2
ptr_func2.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h>
void f(char *);
int main(void){
char str[] = "WTOPIA.";
f(str);
return 0;
}
void f(char *str){
char *p;
for(p = str; *p != '\0'; p++)
printf("[%p] '%c' %s\n", p, *p, p);
}
|
ptr_func2.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_func2
[0x7fff5fbff3c0] 'W' WTOPIA.
[0x7fff5fbff3c1] 'T' TOPIA.
[0x7fff5fbff3c2] 'O' OPIA.
[0x7fff5fbff3c3] 'P' PIA.
[0x7fff5fbff3c4] 'I' IA.
[0x7fff5fbff3c5] 'A' A.
[0x7fff5fbff3c6] '.' .
今度は逆に, アドレスを返す関数, [ポインタ関数] を作成してみよう.
func_ptr.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 | #include <string.h>
#include <stdlib.h>
#include <stdio.h>
char *f(void);
int main(void){
char *y;
y = f();
printf("(2) %s [%p]\n", y, y);
free(y);
return 0;
}
char *f(void){
char str[8] = "WTOPIA.";
char *x;
x = malloc( strlen(str) + 1 );
/*
malloc によって割り当てたメモリ領域は, 解放すれまでメモリは消費される.
*/
if(x == NULL) exit(1);
strncpy(x, str, strlen(str));
printf("(1) %s [%p]\n", x, x);
return x;
}
|
func_ptr.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./func_ptr
(1) WTOPIA. [0x100100080]
(2) WTOPIA. [0x100100080]
メモリ・リーク (Memory Leak) とは,
プログラムが常に動作しているような場合, malloc で割り当てたメモリ領域を free で適切に解放しないと, メモリ消費が増えてゆく [メモリリーク] が起こる. メモリリークが起こり, メモリを消費尽くすと, システムがダウンする.
ptr_to_func.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h>
void f(void);
int main(void){
void (*pf)(void) = f;
pf();
return 0;
}
void f(void){
printf("Hello World!\n");
}
|
ptr_to_func.c の実行結果は:
[cactus:~/code_c/c_tuts]% ./ptr_to_func
Hello World!