文責:30-50-80(http://3580.net/)

1:○じめに

 敢えてこんばんは。いろいろと必死(お察しください)な30-50-80です。プログラマだらけで音師・絵師などの素材系があまりいないことでいわずと知れた本サークルですが、逆に言えばプログラマはたくさんいてもどんなプログラマが多いのかということはあまり知られていません。というわけで、みんなどんな感じなのだろうかと興味半分で無作為(1年生から院1年生まで)に15人に対してプログラムのテストっぽい問題をやらせてみました。ただしさすがに簡単な問題だと似た感じのプログラムしか書かないと思ったので、個性が出る(出てしまう)ようにちょっとした仕掛けを導入しました。またコンパイラはMicrosoft Visual Studio .netを使用しました。

2:問題

0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

 コンソールで上図のような出力をするプログラムを書いてください。

#include <stdio.h>
#define tate 5
#define yoko 5

当初はこんな問題でしたが、これを出して5分後に突然・・・

3:仕様変更

1 7 13 19
2 8 14 20
3 9 15 21
4 10 16 22
5 11 17 23
6 12 18 24

 コンソールで右図のような出力をするプログラムを書いてください。

#include <stdio.h>
#define tate 6
#define yoko 4

 プログラマにとってもっとも憎き出来事、仕様変更を取り入れてみました。これによって、仕様変更する前のプログラムをいかに変えるか、もしくは破棄するかなどといったことも見てみたいと思います。

4:答案

かたっぱしから見ていきたいと思います。

No.0x01

#include <stdio.h>
#define tate 6
#define yoko 4
int main(){
 int count=1;
 for(int i=0;i<tate*yoko;i++){
  printf("%d",count);
   printf(" ");
   count+=tate;
  }
 }
 return 0;
}

完全に動作しました。このプログラムの特徴としては、for文の中でIを宣言しているところと、ちゃんと空白を表現しているところと、出力する時の数字を足し算引き算でむりやりかえている(iを使っていない)ところがポイントです。

No.0x02

#include <stdio.h>
#define tate 6
#define yoko 4

int main()
{

完全に動作しました。return 0;は無くてもちゃんと通りました。(※コンパイラはVS.net)また、コメントの#defineで小文字ですが、言われてみたらその通りです。ごめんなさい。ちなみにこれを使えとは一言も書いてません。

No.0x03

#include <stdio.h>
#define tate 6
#define yoko 4

int main(){
 int i,j;
 for(i=1;i<=tate;i++){
  for(j=0;j<yoko;j++){
   printf("%d ",j*tate+i);
  }
  printf("\n");
 }
}

完全に動作しました。このプログラムの特徴としては、iが1から、jが0から始まっていることです。仕様変更がちょっと響いてる感じです。

No.0x04

#include <stdio.h>
#define tate 6
#define yoko 4

void main(){
 int i;int j;
 for(i=0;i<tate;i++){
  for(j=0;j<yoko;j++){
   printf("%d ",i+j*tate+1);
  }
 }
 exit(0);
}

コンパイラは通りませんでした。というか無駄にexit(0)が入っていたのが仇でした。さらに、このexit(0)を無くしても改行されていないため、結果が横にずらーっと並びます。何気なくvoid main()は初めてですね。それと、変数宣言がそれぞれにintとついてるのが特徴。

No.0x05

#include <stdio.h>
#define tate 6
#define yoko 4
using namespace std;
#include <vector>
int main(void){
 int a[]={1,7,13,19,2,8,
 14,20,3,9,15,21,
 4,10,16,22,5,11,
 17,23,6,12,18,24};
 for(int i=0;i<25;i++)
 {
  cout << a[i] <<' ';
  if((i%5)==4)
    cout << endl;
 }
}

ついにこの手が来ました。全部決め付け。表示するだけだから、こういうのもアリなんです。しかし改行が5個で1回なのとループが25回のおかげで-858993460なる数字が出てきます。表示がcoutってのがいい感じ。

No.0x06

#include <stdio.h>
#define tate 6
#define yoko 4
int tnum=1;
int num,i,j;
for(i=0;i<tate;i++){
 num=tnum;
 for(j=0;j<yoko;j++){
  printf("%d ",num);
  num+=6;
 }
 printf("\n");
 tnum++;
}

main関数がないです。入れてあげたらちゃんと動きました。tnumとnumで2段かませてます。

No.0x07

#include <stdio.h>
#define tate 6
#define yoko 4
int main(){
 int i,j;
 for(i=1;i<=tate;i++){
  for(j=0;j<yoko;j++){
   printf("%d ",(i+j*tate));
  }
  printf("\n");
 }
 return 0;
}

完全動作しました。No.0x03とほぼ一緒です。

No.0x08

#include <stdio.h>
#define tate 6
#define yoko 4
int main(){
 int i,j;
 for(i=1;i<tate;i++){
  for(j=0;j<yoko;j++){
   printf("%d ",i+6*j);}
  printf("\n");}
}

縦1行足りていませんでした。6行目をfor(i=1;i<=tate;i++){にすればちゃんと表示します。閉じる中カッコを

最後の宣言に一緒にくっつけています。

No.0x09

#include <stdio.h>
#define tate 6
#define yoko 4
int main()
{
 int i,k;

 for(i=0;i<tate;i++){
  for(k=0;k<yoko;k++){
   printf("%d ",k*tate+i+1);
  }
  printf("\n");
 }

最後に中カッコが足りていませんでした。つければちゃんと動きます。ループにjではなくkを使ってます。

No.0x0a

#include <stdio.h>
#define tate 6
#define yoko 4
int main(){
 int x=0,y=0,i;

 for(i=0;i<tate*yoko;i++){
  if(i%yoko==0)printf("\n");
  printf("%d",i);
 }
}

コンパイルは通りますが表示とかが仕様変更前みたいな感じになってます。Xとy
を宣言しているけど使っていません。ひさしぶりの1段for文構成。

No.0x0b

#include <stdio.h>
#define tate 6
#define yoko 4
void main(){
 int cnt,cnt2; cnt=1;cnt2=0;
 while(cnt2<=tate*yoko){
  cnt+=tate; printf(" %d",cnt);
  cnt2++;
  if(cnt2%yoko==0){cnt-=tate*(yoko-1);
   printf("\n");}
 }
}

コンパイルは通りますが表示する数字がよくわかりません。Whileを使ってるのはこれだけです。変数の初期化が独特です。また、printfなどが右側に書かれてます。

No.0x0c

#include <stdio.h>
#define tate 6
#define yoko 4
int main()
{
 int i,j;

 for(i=0;i<tate;i++)
 {
  for(j=0;j<yoko;j++)
  {
   printf("%d ",i+j*tate+1);
  }
  putchar('\n');
 }
 return 0;
}

完全に動作しました。中カッコは他とまとめずに全部1行ずつ使っているのが特徴的。

No.0x0d

#include <stdio.h>
#define tate 6
#define yoko 4
int main(char* argv[],int argc){
 int i,j;
 for(i=0;i<tate;i++){
  for(j=0;j<yoko;j++)
   printf("%d ",tate*j+i+1);
  printf("\n");
 }
 return 0;
}

完全に動作しました。main()の引数をちゃんと書いてます。

No.0x0e

#include <stdio.h>
#define tate 6
#define yoko 4
int t,y;
int i=1;
for(t=0;t<tate;t++){
 for(y=0;y<yoko;y++)
  printf("%d ",
 (i=(i+tate-1)mod(tate*yoko)+1));
 printf("\n");
}

main()が無いです。modも%じゃないと通りませんでした。さらにちゃんと入れてみても「7 13 19 1」の繰り返し

でした。ループ用変数としてt,yを使っています。

No.0x0f

#include <stdio.h>
#define tate 6
#define yoko 4
int main(int argc,char* argv[]){
 int num=tate*yoko,skip=tate;
 for(int i=0;i<num*skip;i+=skip){
  printf("%d ",i%25);
  if((i/skip)%yoko==yoko-1)putchar('\n');
 }
 return 0;
}

微妙に惜しかったです。こちらも引数をちゃんと書いてます。i%25が原因かと。

No.0x10

#include <stdio.h>
#define tate 6
#define yoko 4
int main(){
 printf("1 7 13 19\n");
 printf("2 8 14 20\n");
 printf("3 9 15 21\n");
 printf("4 10 16 22\n");
 printf("5 11 17 23\n");
 printf("6 12 18 24\n");
 return 0;
}

自分の答案です。当たり前ですが完全に動作します。

5:総評

ヘタなことはしないに限る。コレに尽きると思います。出来ることをきっちりやるほうが意外と手っ取り早いのかもしれません。そもそも、このやり方だとコンパイルしてエラーの出たところを修正するというやり方ができないため、このくらいの物でもエラーのひとつやふたつくらい出てもすぐ直せばよいだけなので、この実験自体があんまりよくないものだと言うことがわかりました。だめじゃん。

6:その他

変数の宣言する際、どんな変数を仮置きするかというのをまとめてみました。

No.0x01
int count=1; int I=0;
No.0x02
int i,j;
No.0x03
int i,j;
No.0x04
int i;int j;
No.0x05
int a[]={1,7,13,(略)};int i=0;
No.0x06
int tnum=1;int num,i,j;
No.0x07
int i,j;
No.0x08
int i,j;
No.0x09
int i,k;
No.0x0a
int x=0,y=0,i;
No.0x0b
int cnt,cnt2;
No.0x0c
int i,j;
No.0x0d
int i,j;
No.0x0e
int t,y;int i=1;
No.0x0f
int num=tate*yoko,skip=tate;int i=0;
No.0x10
(宣言せず)

どう見てもi,jが大人気です。数学の行列に影響されていると思われます。tate・yokoの頭文字をとったty派もいました。自分だとxyやmnやabなどを気分で使います。