『Cプログラミング診断室』目次次(第3章 上司が問題 はじめに)

第2章 これでもプロ

まとめ


下手だ、下手だといっぱい書いていますが、現在下手であることは気にすることはまったくあり ません。最初から上手な人などいません。私だって、プログラムを始めたばかりのころは、今思え ば、極めて下手なプログラムを書いていました。「より上手に」だけを少しづつ続けていくことが 何よりです。

前にも書きましたが、しっかり本やマニュアルを読み、上手と思われるソースリストを読みあさ り、自分より上手と思う人がいれば、お土産でも提げていって教えをこうことをしてください。プ ロの人は、開発手法、開発スケジュール管理などの本も必ず読んでください。もちろん、英語の勉 強も忘れないようにしてください。日頃から英文マニュアルや英文のコンピュータ関連書物を読ん でも十分です。

いつも感じることですが、C言語が下手というより、コンピュータ自体への理解不足とか、コン ピュータ言語の一般常識に欠けているために下手になっている場合がほとんどです。Pascalで書い ても、 FORTRANで書いても、やはり同じくらい下手なプログラムになってしまうでしょう。ある程 度の幅広い知識がないと、いくらC言語だけ勉強しても中級レベルになるのは困難でしょう。大学 の一般教養は何の役に立つか怪しいですが、コンピュータ関連の諸知識の有無は重要です。興味本 位でかまいませんが、できるだけいろいろなものを吸収するようにして見てください。そうすると、 もう一度プログラム言語の勉強をするとき、一段高いレベルから考えられるようになり、プログラ ムも見違えるようになることでしょう。

それから、決してコンピュータを恐がらないで欲しい。もし変なことをしたらとかというふうに は考えないで欲しい。間違えたからといって、コンピュータがあなたを食べたり、暴力を振るった りはしないでしょう。普通なら、エラーメッセージの洪水になるくらいで、最悪でもハードディス クがダメになって、再フォーマット程度でしょう。いろいろなトラブルに出合うことで経験が積ま れていきます。子供のころよく玩具を壊していた人だけが、大きくなると器用にいろいろな機械や 電器製品を直せるようになります。どんどん試してください。そして、どーしてかなと考える癖を つけることでしょう。そうすれば、あとは知らないうちに中級レベルでしょう。

美しいパズルとは

ナンプレ問題
自動生成


これで、今日から
貴方もパズル作家

Cパズル
プログラミング
〜再帰編〜


リスト2−4 修正版

     1  /********************************************************************************/
     2  /*                                                                              */
     3  /*                              キー入力関数                                    */
     4  /*                                                                              */
     5  /*      管理責任者      1991/1/1        daredesyou                              */
     6  /*                      1991/2/2        daremoinaimitai                         */
     7  /*                                                                              */
     8  /*      作成    1991/1/1        dareka                                          */
     9  /*                                                                              */
    10  /********************************************************************************/
    11  
    12  #include <stdio.h>
    13  #include <draw.h>
    14  #include <kernel.h>
    15  #include <data.ext>
    16  #include <mes.h>
    17  #include <tags.h>
    18  
    19  #define UNDER_LINE      0x5f
    20  #define MAXBLINK        50
    21  #define KSHIFTJ         0x8140                  /* 漢字最小コード       */
    22  #define KSHIFTJE        0xeefc                  /* 漢字最大コード       */
    23  #define KKI             0x004b
    24  #define KKO             0x0048
    25  #define MASKHIGH        0xff00                  /* 上位バイトのマスク   */
    26  #define MASKLOW         0x00ff                  /* 下位バイトのマスク   */
    27  #define MOUSE_LEFT      1                       /* マウス       左      */
    28  #define MOUSE_DOWN      2                       /*              下      */
    29  #define MOUSE_UP        3                       /*              上      */
    30  #define MOUSE_RIGHT     4                       /*              右      */
    31  
    32  
    33  #define BUFMAX          60
    34  extern  unsigned char   Cursor;
    35  extern  char    kbbuf[BUFMAX];
    36  extern  char    parameter[10][10];
    37  
    38  int     EXIT_CHAR;
    39  
    40  /*------------------            static  functions               ----------------*/
    41  
    42  static  keyinput_sub();
    43  static  control_keycode();
    44  static  storedata();
    45  static  realchk();
    46  
    47  /********************************************************************************/
    48  /*      キー入力(メイン)                                                      */
    49  /*                                                                              */
    50  /*      作成    1991/1/1        dareka                                          */
    51  /********************************************************************************/
    52  keyinput_main(fs,pkt)
    53    int   fs;
    54    int   pkt[4];
    55  {
    56          int     i, col,kflag;
    57          int     rets = GET_OK;
    58          int     keyin_cx;
    59          int     keyin_cy;
    60          int     keyin_noc;
    61  
    62          col        = pkt[0];
    63          keyin_cx   = pkt[1];
    64          keyin_cy   = pkt[2];
    65          keyin_noc  = pkt[3];
    66          kflag      = fs;
    67  
    68          if (keyin_noc >= BUFMAX)
    69                  keyin_noc = BUFMAX - 1;
    70  
    71          for(i = 0; i <= keyin_noc; i++)
    72                  kbbuf[i]=0;
    73  
    74          if (keyinput_sub(col,keyin_cx,keyin_cy,keyin_noc,kflag) == TOPF)
    75                  rets = TOPF;
    76  
    77          return (rets);
    78  }
    79  
    80  /********************************************************************************/
    81  /*      文字列の取得                                                            */
    82  /*                                                                              */
    83  /*      作成    1991/1/1        dareka                                          */
    84  /********************************************************************************/
    85  get_str(fs, col, x, y, size, type)
    86    int   fs, col, x, y, size, type;
    87  {
    88          int     pkt[4];
    89  
    90          Cursor = type;
    91          pkt[0] = col;
    92          pkt[1] = x;
    93          pkt[2] = y;
    94          pkt[3] = size;
    95  
    96          return  keyinput_main(fs, pkt);
    97  }
    98  
    99  /********************************************************************************/
   100  /*      数のセット  (? 意図が良く分かんない)                                 */
   101  /*                                                                              */
   102  /*      作成    1991/1/2        dareka                                          */
   103  /********************************************************************************/
   104  SetNumber( ptr )
   105    char  *ptr;
   106  {
   107          char    *ptr_save = ptr;
   108          char    buf[100], *bufptr;
   109          int     num;
   110  
   111          for ( bufptr=buf; *ptr; ++ptr, ++bufptr ) {
   112                  if ( *ptr == '$' ) {                    /*   '$数字'    */
   113                          ++ptr;
   114                          if( ! isdigit( *ptr ) ) {
   115                                  beep();
   116                                  return (GET_ERR);       /* エラー */
   117                          }
   118                          num = *ptr - '0';
   119                          strcpy( buf, parameter[num] );
   120                          bufptr = buf + strlen(buf);
   121                  }
   122                  else {
   123                          *bufptr = *ptr;
   124                  }
   125          }
   126          *bufptr = '\0';
   127  
   128          strcpy(ptr_save, buf);
   129          return  NO_GET;
   130  }
   131  
   132  /********************************************************************************/
   133  /*      数のキー入力                                                            */
   134  /*                                                                              */
   135  /*      作成    1991/1/3        dareka                                          */
   136  /*      変更    1991/1/3        fuji                                            */
   137  /********************************************************************************/
   138  keyinput_num(col, x, y, size)
   139    int   col, x, y, size;
   140  {
   141          for(;;) {
   142                  if (get_str(11, col, x, y, size, UNDER_LINE) == TOPF)
   143                          return (TOPF);
   144  
   145                  if( keyin_stat == -2 || keyin_stat == -3)
   146                          break;
   147  
   148                  if (SetNumber(kbbuf) == GET_ERR) {
   149                          beep();
   150                          continue;
   151                  }
   152                  if (realchk(kbbuf)){
   153                          beep();
   154                          continue;
   155                  }
   156                  break;
   157          }
   158          return (GET_OK);
   159  }
   160  
   161  /********************************************************************************/
   162  /*      文字の取得(キーボード|マウス)                                        */
   163  /*                                                                              */
   164  /*      作成    1991/1/4        dareka                                          */
   165  /*      変更    1991/4/20       fuji            mi -->  mouse_code              */
   166  /********************************************************************************/
   167  get_chr()
   168  {
   169          int     mouse_code, CC;
   170  
   171          mouse_code = 0;
   172          while ((CC = io_conin()) == '\0') {
   173                  if (mskb_flg == 1) {
   174                          if( mouse_code = io_mouse(0) )
   175                                  break;
   176                  }
   177          }
   178  
   179          switch( mouse_code ) {
   180          case MOUSE_LEFT:
   181                  CC = KRTN;
   182                  outputc(CC);
   183                  break;
   184          case MOUSE_RIGHT:
   185          case MOUSE_UP:
   186          case MOUSE_DOWN:
   187                  CC = ' ';
   188                  outputc(CC);
   189          }
   190  
   191          return (CC);
   192  }
   193  
   194  /*------------------------------------------------------------------------------*/
   195  /*      static 宣言     keyinput_sub, control_keycode でのみ使用                */
   196  /*------------------------------------------------------------------------------*/
   197  
   198  static  int     _wrdbuf[BUFMAX], *_wrdbufptr;
   199  static  int     _xx, _yy;
   200  
   201  /*------------------------------------------------------------------------------*/
   202  /*      キー入力の実体部分                                                      */
   203  /*                                                                              */
   204  /*      作成    1991/1/3        dareka                                          */
   205  /*      変更    1991/4/4        fuji            wrdbufを外に、chr_pntを削除     */
   206  /*      変更    1991/4/5        fuji            xx, yy を外に                   */
   207  /*      変更    1991/4/6        fuji            通常のキーのときを別関数にした  */
   208  /*------------------------------------------------------------------------------*/
   209  static  keyinput_sub(col,keyin_cx,keyin_cy,keyin_noc,fs)
   210    int   col;
   211    int   keyin_cx;
   212    int   keyin_cy;
   213    int   keyin_noc;
   214    int   fs;
   215  {
   216          unsigned int    as;
   217          int     i;
   218          int     han_su;
   219          int     zenkaku_flg;
   220          int     state;
   221  
   222          switch( fs ) {
   223          case 14:        
   224                  zenkaku_flg = 1;        break;
   225          case 15:        
   226                  zenkaku_flg = 2;        break;
   227          default:
   228                  zenkaku_flg = 0;        break;
   229          }
   230  
   231          for( state=1 ; state ; ) {
   232                  keyin_stat = 0;
   233                  if (keyin_noc == 0)  return (GET_OK);
   234  
   235                  han_su = 0;
   236                  _wrdbufptr = _wrdbuf;
   237  
   238                  _xx = keyin_cx;
   239                  _yy = keyin_cy;
   240                  color(col);
   241                  locate(_xx, _yy);
   242                  for (i = 1; i <= keyin_noc; i++ )
   243                          io_cout(Cursor);
   244  
   245                  do {
   246                          as = get_chr();
   247  
   248                          state = special_keycode( as, 
   249                                          keyin_cx, keyin_cy, keyin_noc,  &han_su );
   250  
   251                          if( state == 0 )
   252                                  state = normal_keycode( as, zenkaku_flg, &han_su );
   253  
   254                          switch( state ) {
   255                          case 1:
   256                                  continue;
   257                          case 3:
   258                                  goto ret;
   259                          case 4:
   260                                  return  GET_OK;
   261                          case 5:
   262                                  return  TOPF;
   263                          }
   264                          if( state == 2 )
   265                                  break;
   266  
   267                  } while( han_su < keyin_noc);
   268          }
   269    ret:
   270          storedata( _wrdbuf, _wrdbufptr - _wrdbuf,
   271                                  kbbuf, keyin_cx, keyin_cy, keyin_noc );
   272          return ( GET_OK );
   273  }
   274  
   275  /*------------------------------------------------------------------------------*/
   276  /*      制御キーの処理                                                          */
   277  /*                                                                              */
   278  /*      戻り値:         呼びだし側に戻った時の処理                              */
   279  /*                                                                              */
   280  /*              0       処理を続ける                                            */
   281  /*              1       continue;                                               */
   282  /*              2       break;                                                  */
   283  /*              3       goto ret;                                               */
   284  /*              4       return (GET_OK);                                        */
   285  /*              5       return (TOPF);                                          */
   286  /*                                                                              */
   287  /*      作成    1991/1/3        dareka                                          */
   288  /*      変更    1991/4/1        fuji            関数名の変更                    */
   289  /*      変更    1991/4/4        fuji            wrdbufを外に、chr_pntを削除     */
   290  /*      変更    1991/4/5        fuji            xx, yy を外に                   */
   291  /*------------------------------------------------------------------------------*/
   292  static  special_keycode( as, keyin_cx, keyin_cy, keyin_noc, han_su )
   293    unsigned int  as;
   294    int           keyin_cx, keyin_cy, keyin_noc;
   295    int           *han_su;
   296  {
   297          int     i;
   298  
   299          if ((as & 0xff00) == B_PFKEY) {
   300                  beep();
   301                  return  1;
   302          }
   303  
   304          switch (as) {
   305          case KDEL:
   306                  kbbuf[0] = '\0';
   307                  return  2;
   308          case KESC:
   309                  *_wrdbufptr++ = as;
   310                  return  1;
   311          case KBS:
   312                  keyin_stat = -2;
   313                  locate(keyin_cx, keyin_cy);
   314                  for( i=1 ; i<=keyin_noc; i++ )
   315                          io_cout(Cursor);
   316                  return  4;
   317          case KRTN:
   318                  if (EXIT_CHAR != 0 && _wrdbufptr[-1] == EXIT_CHAR) {
   319                          delng_flg = 0;
   320                          kpf = 0;
   321                          return  5;
   322                  }
   323                  if ( _wrdbufptr == _wrdbuf  &&  kbbuf[0] == '\0') {
   324                          keyin_stat = -3;
   325                          locate(keyin_cx, keyin_cy);
   326                          io_cout(' ');
   327                  }
   328                  return  3;
   329          case UPA:
   330          case DOWNA:
   331          case RIGHTA:
   332          case KHOME:
   333          case KCLR:
   334                  beep();
   335                  return  1;
   336          case LEFTA:                             /****** 1文字戻す ******/
   337                  if ( _wrdbufptr == _wrdbuf ) {  /* すでに先頭である     */
   338                          kbbuf[0] = '\0';
   339                          return  2;
   340                  }
   341                  else {                          /* 先頭でないので、戻す */
   342                          _wrdbufptr--;
   343                          if( ( _wrdbufptr[-1] >= 0x82 ) &&
   344                              ( _wrdbufptr[-1] <= 0x9f ) &&
   345                              ( _wrdbufptr[ 0] >= 0x3f ) &&
   346                              ( _wrdbufptr[ 0] <= 0xfc )  ) {
   347                                                          /* 漢字 */
   348                                  _xx -= 2;
   349                                  (*han_su) -= 2;
   350                                  _wrdbufptr--;
   351                                  locate( _xx, _yy );
   352                                  io_cout( Cursor );
   353                                  io_cout( Cursor );
   354                          }
   355                          else{                           /* 非漢字 */
   356                                  _xx--;
   357                                  (*han_su)--;
   358                                  locate( _xx, _yy );
   359                                  io_cout(Cursor);
   360                          }
   361                  }
   362                  return  1;
   363          }
   364  
   365          if (0 < as && as < 0x20) {
   366                  beep();
   367                  return  1;
   368          }
   369  
   370          return  0;
   371  }
   372  
   373  /*------------------------------------------------------------------------------*/
   374  /*      通常キーの処理(含む漢字)                                              */
   375  /*                                                                              */
   376  /*      戻り値:         呼びだし側に戻った時の処理                              */
   377  /*              0       処理を続ける                                            */
   378  /*              1       continue;                                               */
   379  /*                                                                              */
   380  /*      作成    1991/4/6        fuji            通常キー時の別関数として作成    */
   381  /*------------------------------------------------------------------------------*/
   382  static  normal_keycode( as, zenkaku_flg, han_su ) 
   383    unsigned int  as;
   384    int           zenkaku_flg;
   385    int           *han_su;
   386  {
   387          int     chr_conv;
   388  
   389          if (as >= KSHIFTJ && as <= KSHIFTJE ){  /* 漢字だよ */
   390                  chr_conv = as;
   391                  if ( zenkaku_flg == 0) {
   392                          beep();
   393                          return  1;
   394                  }
   395                  *_wrdbufptr++ = (chr_conv >> 8) & MASKLOW;
   396                  *_wrdbufptr++ =  chr_conv & MASKLOW;
   397                  locate(_xx,_yy);
   398                  io_cout( _wrdbufptr[-2] );
   399                  io_cout( _wrdbufptr[-1] );
   400                  _xx +=2;
   401                  han_su += 2;
   402          }
   403          else{                                   /* 漢字じゃないよ */
   404                  if ( zenkaku_flg == 1) {
   405                          beep();
   406                          return  1;
   407                  }
   408                  locate(_xx, _yy);
   409                  io_cout(as);
   410                  *_wrdbufptr++ = as;
   411                  _xx++;
   412                  han_su++;
   413          }
   414  
   415          return  0;
   416  }
   417  
   418  /*------------------------------------------------------------------------------*/
   419  /*      データのセーブ                                                          */
   420  /*                                                                              */
   421  /*      作成    1991/1/6        dareka                                          */
   422  /*      変更    1991/4/6        fuji            keybufptrの利用                 */
   423  /*------------------------------------------------------------------------------*/
   424  static  storedata(wrdbuf, chr_pnt, keybuf, keyin_cx, keyin_cy, keyin_noc )
   425    int   wrdbuf[], chr_pnt;
   426    char  keybuf[];
   427    int   keyin_cx, keyin_cy, keyin_noc;
   428  {
   429          char    *keybufptr = keybuf;
   430          int     i, s, scount, zenkaku_flg;
   431  
   432          scount = zenkaku_flg = 0;
   433  
   434          for (i = 0; i < chr_pnt; i++){
   435                  if (wrdbuf[i] & MASKHIGH){
   436                          if (zenkaku_flg == 0){
   437                                  zenkaku_flg = 1;
   438                                  *keybufptr++ = KESC;
   439                                  *keybufptr++ = KKI;
   440                          }
   441                          if (zenkaku_flg == 1){
   442                                  *keybufptr++  = wrdbuf[i]>>8;
   443                                  *keybufptr++  = wrdbuf[i];
   444                          }
   445                  } else if(zenkaku_flg == 1){
   446                          zenkaku_flg = 0;
   447                          *keybufptr++ = KESC;
   448                          *keybufptr++ = KKO;
   449                          *keybufptr++ = wrdbuf[i];
   450                  } else {
   451                          *keybufptr++ = wrdbuf[i];
   452                  }
   453          }
   454          *keybufptr = '\0';
   455  
   456          conv_chr_val(kbbuf);
   457  
   458          if( (s = keyin_noc - strlen(keybuf) ) < 0 )
   459                  s = 0;
   460  
   461          locate(keyin_cx + strlen(kbbuf),keyin_cy);
   462          printf( "%*s", s, "" ); /* 注意:ちゃんとしていないCにはないことがある */
   463  }
   464  
   465  /********************************************************************************/
   466  /*      y/n のキー入力  (入力メッセージ付き)                                  */
   467  /*                                                                              */
   468  /*      作成    1991/1/6        dareka                                          */
   469  /********************************************************************************/
   470  keyinput_yn(mes)
   471    int mes;
   472  {
   473          int     flag;
   474  
   475          dsp_str(SKYBLUE, 0, 0, "OK[Y/N]= *");
   476          flag  = get_yn();
   477          clear_guide();
   478          return (flag);
   479  }
   480  
   481  /********************************************************************************/
   482  /*      y/n のキー入力  (入力のみ)                                            */
   483  /*                                                                              */
   484  /*      作成    1991/1/6        dareka                                          */
   485  /********************************************************************************/
   486  get_yn()
   487  {
   488          for(;;) {
   489                  switch( get_chr() ) {
   490                  case 'y':
   491                  case 'Y':
   492                  case 13:
   493                          return  0;
   494                  case 'n':
   495                  case 'N':
   496                  case ' ':
   497                          return  1;
   498                  default:
   499                          beep();
   500                  }
   501          }
   502  }
   503  
   504  /*------------------------------------------------------------------------------*/
   505  /*      実数のチェック                                                          */
   506  /*              戻り値          0:正常        1:異常                        */
   507  /*                                                                              */
   508  /*      作成    1991/4/1        dareka                                          */
   509  /*------------------------------------------------------------------------------*/
   510  static  realchk(s)
   511    char *s;
   512  {
   513          int     seisuu_bu, syousuu_bu;
   514  
   515          for( ; *s ; ++s ) {
   516                  seisuu_bu = syousuu_bu = 0;
   517                  if( *s=='+' || *s=='-' )
   518                          ++s;
   519                  for( ; isdigit(*s) ; ++s )
   520                          seisuu_bu = 1;
   521                  if( *s == '.' ) {
   522                          ++s;
   523                          for( ; isdigit(*s) ; ++s )
   524                                  syousuu_bu = 1;
   525                  }
   526                  if( seisuu_bu==0 && syousuu_bu==0 )
   527                          return  1;
   528  
   529                  if( ! ( *s == '/' || *s == '*' ) )
   530                          break;
   531          }
   532  
   533          return  *s ? 1 : 0;
   534  }
   535  
   536  /********************************************************************************/
   537  /*      時間待ち        (この関数は問題が大き過ぎるので、修正していない!)    */
   538  /*                                                                              */
   539  /*      作成    1991/4/1        dareka                                          */
   540  /********************************************************************************/
   541  wait_5()
   542  {
   543          long i;
   544  
   545          for (i = 0; i < 50000; i++) ;
   546  }
   547  
   548  /********************************************************************************/
   549  /*                      EOF  "keyin.c"                                       */
   550  /********************************************************************************/


Copyright1996 Hirofumi Fujiwara. No reproduction or republication without written permission
『Cプログラミング診断室』目次次(第3章 上司が問題 はじめに)