内容

C言語の基礎その3

文字列操作


ポインタ

ポインタは変数のメモリ上でのアドレス(番地)を示す。例えば、変数を箱にたとえると、ポインタはその箱がどこに置かれているかを示す。

ポインタは宣言文の中で変数名の前にアスタリスク"*"をつけて宣言する。

 

int x; /* 普通の変数 */

int *y; /* ポインタ */

 

ポインタに関する演算子には"""*"がある。&は変数のアドレスを返す。また、*ポインタが指している変数の中身を表す

 

変数のアドレスを表す

*

ポインタの指している中身を表す。

 

x

int x; と宣言されているので、これは普通の変数である。ポインタではない。

例:

 x = 4;

&x

変数xのアドレスを表す。

例:

 y = &x; /* xのアドレスをポインタyに代入*/

y int *y;と宣言されているので、ポインタである。

例:

y = &x; /* xのアドレスをポインタyに代入*/

*y

ポインタyの指しているアドレスの中身を表す。

例:

y = &x; /* xのアドレスをポインタyに代入*/

*y = 5; /*yが指しているものに5を代入*/

ポインタのサンプルプログラムを以下に示す。

#include<stdio.h>

main()
{
  int x; /*
変数xを宣言 */
  int *y; /*
変数を指すポインタを宣言 */

  x = 2; /* 変数に値を代入 */

  printf("%d\n", x);

  y = &x; /* ポインタがxを指すようにする */

  *y = 4; /* yxを指しているので */

  /* x4が代入される */
  printf("%d\n", x);

  /* *yは指している中身を表す */

  printf("%d\n", *y);
}

 

ポインタと配列

ポインタは加算と減算が可能である。

int array[5];
int *pointer = &array[0];

上の例では*pointerが指しているもはarray[0]と同じである。ここで、*(array + 1)array[1]と同じ、*(array + 2)array[2]と同じである。括弧の使い方に注意すること

このように、配列のアドレスに1を足すことは、配列の要素を1つ進めることと同じである。

また、上の

*pointer = &array[0]

と書くのと、

*pointer = array

のように配列名だけを書くのは同じことを表す。すなわち、配列名だけの場合は配列の先頭アドレスを示す

ポインタと関数

関数に引数を渡す場合、通常は「値渡し」という方法が取られる。関数に変数aを渡すといっても、実際に渡すのはaの値を渡す。つまり、関数を呼び出す側の変数と、関数が受け取った変数の実体は別のものである。従って、関数にある変数を渡してその内容を加工して返して欲しい場合などには使用できない。

このような場合にはポインタを変数の引数として渡す。

 

#include <stdio.h>

void calc(int *y);

main()
{
  int i = 0;

  calc(&i);
}

void calc(int *y)
{
  *y += 4;
}

 

上の例では、main文の変数iのアドレスを関数calcに渡している。従って、calcの中で計算した結果をmain文の変数iに代入することができる。

配列の場合は以下のように関数に渡すことができる。配列は配列名だけでアドレスを表わすので、送り側で特に&を付ける必要はない。また、1次元配列の場合、引数は[ ]のように要素数を省略できる。ただし、2次元配列の場合は[ ][5]のように、2つ目の引数は省略できない。

 

#include <stdio.h>

void calc(int y[]);

main()
{
  int array[5];

  calc(array);
}

void calc(int y[])
{
  y[0] = 10;
  y[1] = 5;

}

 


文字列操作

文字コード

コンピュータ上で扱われる文字は、すべての文字それぞれについて番号が割り振られている。これを文字コードといい、ASCIIコードやEUCコードなどがある。

ASCIIコードではアルファベットの大文字AZ6590、小文字az97122に割り振られている。

次のプログラムは入力された文字の文字コードを出力するプログラムである。

#include <stdio.h>

main()
{
  char str;
  int code;

  scanf("%c", &str);


  code = (int)str;
  printf("%c : %s\n", str, code);
}

 

文字列

C言語では文字列を扱う特別なデータ型が用意されているわけではない。文字列は1文字だけを扱うchar型の配列として取り扱われる。

文字型データはchar型変数を用いて、

char a; a = 'A';

のように取り扱われる。char型に文字を代入する場合'でくくる。

文字列を取り扱う場合には、char型配列に一文字ずつ代入することでも行なえる。

char buf[7];

buf[0] = 'J';
buf[1] = 'a';

buf[2] = 'p';
buf[3] = 'a';
buf[4] = 'n';
buf[5] = '\0';

この例で、'n'の次の\0ヌル文字と呼ばれ、文字列の終端を表す。このように配列の要素一つずつに代入する場合には終端を表すヌル文字も代入する必要がある。従って、配列サイズは文字列+「ヌル文字」分必要である。

このように一文字ずつ代入するのは手間がかかるため、文字列定数と呼ばれるものが用意されている。この定数は"で囲まれた"computer"のように表す。これは、

 

c

o

m

p

u

t

e

r

\0

 

のようなメモリ配置となり、終端には\0が自動的に付加される。

文字列定数は、文字そのものの列を表しておらず、その文字列の格納されている場所の先頭アドレスを表す。従って、char型ポインタを用いて次のようにアドレスを得ることができる。

char *buf;

buf = "computer";

初期化付きで文字列を宣言する場合は以下のように行なう。配列サイズは省略しても必要なサイズが自動的に確保される。

char buf[9] = "computer";

もしくは

char buf[] = "computer";

scanfで文字列を入力する場合には以下のように行なう。scanfは第二引数以降にポインタを渡す。そのため、通常はアドレスを表す&を必要とする。配列の場合は配列名が先頭アドレスを表すため&を付ける必要はない

char buf[256];

scanf("%s", buf);

scanf%sで文字列を入力した場合、自動的にヌル文字が終端に代入される。