@blog.justoneplanet.info

日々勉強

ポインタを使ってみる

以下のように書いてみる。

int x = 1;
int *ip;
ip = &x;
printf("%p", ip);// 0xbfffef28

ipにはメモリのアドレスが入ってることが分かる。アドレスが指している値を読むには以下のようにする。

int x = 1;
int *ip;
ip = &x;
printf("%d", *ip);// 1

*ipを書き換えたらxの値はどうなるのか?

int x = 1;
int *ip;
ip = &x;
printf("%d", *ip);// 1
(*ip)++;
printf("%d", x);// 2

まぁ、当然書き換わる。

アドレスの操作

*が付いている場合はアドレスの操作になる。

int x = 1;
int *a = &x;

値の操作

以下のようにすると値を操作できる。

int x = 1;
int *a = &x;
a = 2;

■ヌルポインタ

アドレスを代入していないことを示すためにヌルポインタが存在する。

int main(int argc, char *argv[])
{
    int *a = NULL;
    int x = 2;
    a = &x;
    printf("%d", *a);// 2
}

以下のようにも記述できる。

int main(int argc, char *argv[])
{
    int *a = NULL;
    int x = 2;
    a = &x;
    printf("%d", *a);// 2
}

当然だけど全く関係ないアドレスにアクセスすればバグになる。

■関数の引数としてのポインタ

引数として与えられた変数の値を入れ替えるには以下のようにする。

swap(&x, &y);

cの関数において引数は全て値渡しとなるためアドレスを渡す必要があり、以下のようにすることで入れ替えすることができる。

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

■ポインタと配列

以下のように記述してみる。

int x[] = {1, 2, 3, 4, 5};
int *px;
px = &x[0];
printf("%d", *px);// 1
printf("%d", *(px + 1));// 2
printf("%d", *(px + 2));// 3
printf("%d", *(px + 3));// 4
printf("%d", *(px + 4));// 5

pxは配列xの0番目を参照し、+1ごとに配列の右を参照する。低レイヤーな言語を触るとメモリが見えるのが面白いよね。

ちなみに(やってはいけないが)-1すると以下のようになる。

printf("%p", (px - 1));//0xbfffef14
printf("%d", *(px - 1));//-1073746152

■文字ポインタと関数

以下のような文字定数は文字の配列でもある。

"This is a pen."

記憶領域においては末端文字\0が配列の最期にあるため1文字大きい。

char *str = "This is a pen.";

Cでは文字列全体を一つの単位として処理するような演算子は提供されていない。

ちなみ以下の記述において前者は文字列を変更することができるがアドレスが変わることはない。後者はアドレスを変える事ができるが文字列を変えることはできない。

char strA[] = "This is a pen.";
char *strB = "This is a pen.";

ちなみに以下のようにして上述の文字列を出力することができる。

char strA[] = "This is a pen.";
for(int i = 0; i < sizeof(strA) / sizeof(strA[0]); i++){
    printf("%c", strA[i]);
}
char *strB = "This is a pen.";
while(*strB != '\0'){
    printf("%c", *strB);
    strB++;
}

strcpy

配列
void strcpy(char *s, char *t)
{
    int i = 0;
    while((s[i] = t[i]) != '\0'){
        i++;
    }
}
ポインタ
void strcpy(char *s, char *t)
{
    while((*s = *t) != '\0'){
        s++;
        t++;
    }
}

ふむふむ。なるほど。

strcmp

配列
int strcmp(char *s, char *t)
{
    for(int i = 0; s[i] == t[i]; i++){
        if(s[i] == '\0'){
            return 0;
        }
    }
    return s[i] - t[i];
}
ポインタ
int strcmp(char *s, char *t)
{
    for(; *s == *t; s++, t++){
        if(*s == '\0'){
            return 0;
        }
    }
    return *s - *t;
}

ふむふむ。なるほど。

コメントはまだありません»

No comments yet.

RSS feed for comments on this post.TrackBack URL

Leave a comment