C言語を学んでびっくりしたこと

Java使いがC言語を学んでびっくりしたことを書いてみる。
codepadを使ってみた。これいいね。
知ったときは、僕が使える言語がほとんどサポートされていなかったので、ふーんと思っただけだった。
こうやってちょっと動作確認するにはとても便利だ。


まずはHello Worldだ。これは普通。
http://codepad.org/FVB5fxOw

#include<stdio.h>
int main(void){
  printf("Hello, World!\n");
  return 0;
}


簡単なfor文を書いてみたが、これはうまく動かない。
http://codepad.org/W7A3M0GF

#include<stdio.h>
int main(void){
  for(int i=0; i<10; i++){
    printf("%d\n",i);
  }
  return 0;
}


こっちはうまくいく。
iの宣言はfor文内ではできないみたい。
http://codepad.org/pYVQU2RM

#include<stdio.h>
int main(void){
  int i;
  for(i=0; i<10; i++){
    printf("%d\n",i);
  }
  return 0;
}


配列を宣言してみたが、これはうまく動かない。
http://codepad.org/JpefxGiD

#include<stdio.h>
int main(void){
  int[] ary = {1,2,3,4,5};
  int i;
  for(i=0; i<5; i++){
    printf("%d\n",ary[i]);
  }
  return 0;
}


こっちはうまく動く。
[]は変数につけないといけないみたいだ。
http://codepad.org/gAChg8Hl

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<5; i++){
    printf("%d\n",ary[i]);
  }
  return 0;
}


調子にのって、5個しか定義していないところを、10個までアクセスしてみる。
これはびっくりな結果になった。
http://codepad.org/SwcfSkZb

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<10; i++){
    printf("%d\n",ary[i]);
  }
  return 0;
}

なんかいっぱい出てきた。
JavaならArrayIndexOutOfBoundsExceptionが発生するのに。

1
2
3
4
5
-16121856
-1079685856
1075105060
1073828160
-1079685816


というわけで、配列の要素のポインタを表示させてみる。
http://codepad.org/3ShWWtL1

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<10; i++){
    printf("%p\n",&(ary[i]));
  }
  return 0;
}

ほほー。int分のメモリをどんどん読んでいってるだけなのか。

0xbf9b2444
0xbf9b2448
0xbf9b244c
0xbf9b2450
0xbf9b2454
0xbf9b2458
0xbf9b245c
0xbf9b2460
0xbf9b2464
0xbf9b2468


要素とポインタを表示させてみる。
http://codepad.org/JodwWm6o

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<10; i++){
    printf("%p : %d\n",&(ary[i]),ary[i]);
  }
  return 0;
}

やっぱりどんどん読んでいるだけだ。

0xbf4f6f84 : 1
0xbf4f6f88 : 2
0xbf4f6f8c : 3
0xbf4f6f90 : 4
0xbf4f6f94 : 5
0xbf4f6f98 : -16121856
0xbf4f6f9c : -1085313088
0xbf4f6fa0 : 1075105060
0xbf4f6fa4 : 1073828160
0xbf4f6fa8 : -1085313048


今度は配列の要素を書き換えてみる。
まずは定義した要素数分書き換える。これはうまく動く。
http://codepad.org/muVaUlYT

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<5; i++){
    ary[i] = i;
    printf("%p : %d\n",&(ary[i]),ary[i]);
  }
  return 0;
}


今度は要素数を越えて書き換える。
http://codepad.org/22wYLsgb

#include<stdio.h>
int main(void){
  int ary[] = {1,2,3,4,5};
  int i;
  for(i=0; i<10; i++){
    ary[i] = i;
    printf("%p : %d\n",&(ary[i]),ary[i]);
  }
  return 0;
}

やっぱり怒られた。

Disallowed system call: SYS_socketcall


「やさしいC」に書いてあったことをいろいろ試して勉強していたけど、「やってはいけません」と書いてあることをやってみるのは大事だなと思った。
なぜやってはいけないのかということを、ちゃんと知っておくのは大事なことだと思う。

やさしいC 第3版 [やさしいシリーズ]
高橋 麻奈
価格:¥ 2,625