コピー
プログラムで良く使うのが、変数に値を設定する事です。ここでは値の型によって設定する方法が異なったり、便利な関数を使ったりする方法をご紹介です。値の設定の基本は、"="を挟んで右から左に値をコピーします。あと同じ型同士でないとコンパイルの時にひどく怒られます。無理やり入れたい場合は右側の型を変化(cast)させる手も有りますが初めの内は避けたほうが良いかも
■=でのコピー
#include <stdio.h> int main(int argc,char **argv) { int a; int aa; char b; char c[3]; a = 10; // aに10を設定 aa = a; // aの値をaaに設定 b = 'A'; // cに'A'を設定 // cはcharの連続領域に、[ok]の文字列(string)を設定する場合には、 // 各char領域に値と最後に終端(0x00)を設定する事により文字列となる c[0] = 'o'; c[1] = 'k'; c[2] = 0x00; printf("%d %d %c %s\n",a,aa,b,c); }
gcc main.c ./a.out 10 10 A ok
■関数でコピー
文字列を扱う場合は、予め用意された関数を使うのが良いでしょう。(自前で作っても良いですが)
・strcpy 文字列のポインタから指定した文字列を設定する。
#include <stdio.h> #include <string.h> int main(int argc,char **argv) { char c[3]; strcpy(c,"ok"); printf("%s\n",c); }
$ gcc main.c $ ./a.out ok
文字列(string)の闇
C言語の型として1文字の「文字」(char)は有りますが、連続した文字の「文字列」という型は存在しません。しかしC言語を使ってシステムを作成するには文字列を避けて通れません。数字のみの学術系なら別ですが。
この文字列を表現するのに、連続した文字(char)の領域を利用し、先頭から文字を設定し終わり表す値(0x00)別名ヌル(null)を設定し、先頭からnullまでの連続した領域を文字列として表現しています。注意点は文字列の終わりがnullとしているだけで領域の終わりを指していません。またnullを設定する領域も必要です。ここ勘違いするとstringの闇にはまります。
ちなみにヌルは、ただの0です。0x00は16進数で書いてますが、10進数で書けば0です。アドレスの0番地をヌルポインターとも呼んでます。
配列
値の領域が連続している状態を指します。これを型のサイズ分だけ繰り返して参照させる仕掛けとして、変数に""として表記すると容易に参照できる仕掛けを配列と呼びます。
注意点としては内に型サイズの移動個数を指定できますが、最初は移動しないので0となります。また型の宣言時の[]内の値は領域の末端を指すので1個多め値となります。1つ多めの最初の位置なので、一個前の末端なんです。必要個数だと思えば一安心。ただ、知らないと闇注意報
さらに、アドレスに対して足し算しても同様になりますので知ってて得するTIPSです。
#include <stdio.h> int main(int argc,char **argv) { int a[3]; // int型を3個分 int i; a[0] = 10 ; // 1番目に10をセット。 a[1] = 11 ; // 2番目に11をセット。 a[2] = 12 ; // 3番目に12をセット。 for(i=0;i<3; i++){ printf( "%d : %x %d %d\n",i,a+i,*(a+i),a[i]); } *(a) = 20 ; // 1番目に20をセット。 *(a+1) = 21 ; // 2番目に21をセット。 *(a+2) = 22 ; // 3番目に22をセット。 for(i=0;i<3; i++){ printf( "%d : %x %d %d\n",i,a+i,*(a+i),a[i]); } }
■結果
$ gcc main.c $ ./a.out 0 : 11bcc380 10 10 1 : 11bcc384 11 11 2 : 11bcc388 12 12 0 : 11bcc380 20 20 1 : 11bcc384 21 21 2 : 11bcc388 22 22
繰り返し(for)
条件が合う間は処理を繰り返す
書式
for(初期処理 ; 条件 ; 後処理) 処理
一般的に使う場合は、初期処理で値をセットし、条件で判定させ、後処理で値を変更させる事が多いです。
例題:値aを0から1づつ増加させ、10以下の間は処理を繰り返す。
int foo(void) { int a; for( a = 0 ; a < 10 ; a ++ ) { printf("ok\n" ); } }
■TIPS
先人の知恵ではなけいど、無限ループの正しい作法は、while(1)ではなく
while(1) { printf("help me\n"); }
ではなく、for(;;)らしい
whileは(1)でも判定処理が入ってしまうらしい。都市伝説
for(;;) { printf("help me\n"); }
繰り返し(do-while)
特定の条件において処理を繰り返ししますが、処理後に判定のケース
書式
処理 do - while(条件) ;
例題:処理後にaが1の場合は繰り返す。
int foo(void) { int a =1; int b =0; do { printf("foo\n" ); b++; if ( b > 10 ) a = 0; } while ( a == 1 ) ; }
繰り返し(while)
特定の条件において処理を繰り返しします。
書式
while(条件) 処理 ;
例題:aが1の場合は処理する。を繰り返す。
int foo(void) { int a =1; int b =0; while ( a == 1 ) { printf("foo\n" ); b++; if ( b > 10 ) a = 0; } }
ジャンプ(go to)
特定の場所へ移動することが出来ます。
ただ、作り的に煩雑になるので、あまり使われません。
書式
goto 場所名;
int foo(void) { int a =1; if ( a == 1 ) { goto err; } printf("ok\n" ); return 0 ; err: printf("ng\n" ); return 0 ; }