ProgI

変数のスコープ(Scope:有効範囲)


谷口祐治(taniguchi@cc.u-ryukyu.ac.jp)

目 次


変数のスコープ(Scope:有効範囲)と記憶域クラス

 
変数のスコープ
有効範囲意味
関数関数内全域で有効
ファイルコンパイル・翻訳単位内全域で有効
ブロックブロック内で有効
関数原型関数宣言の内部でのみ有効
 
 
記憶域クラス
記憶域クラス指定子メモリ領域変数の適応範囲
auto(自動変数):省略可動的・スタック局所(local)
static(静的変数)静的局所または大域:宣言されている場所による
extern(外部変数)静的または空大域(global)
register(レジスタ変数)レジスタまたはスタック局所(local):コンパイラの最適化等で自動適応
typedef(型定義)静的または空局所または大域:宣言されている場所による

記憶領域とスコープのサンプルプログラム

  1. 静的記憶と動的記憶
    #include <stdio.h>
    
    int   en = 10;      /* File Scope */
    void  inc_n(void);
    
    main(){
      printf("befor function           en=%2d\n\n",en);
      inc_n();
      inc_n();
      inc_n();
      printf("after function           en=%2d\n\n",en);
    }
    
    void inc_n(void){
      static  int sn = 0;  /* Block Scope */
      auto    int an = 0;  /* Block Scope */
      extern  int en;      /* File Scope  */
    
      printf("befor n++  sn=%2d  an=%2d  en=%2d\n",sn,an,en);
      sn++;
      an++;
      en++;
      printf("after n++  sn=%2d  an=%2d  en=%2d\n\n",sn,an,en);
    }
    
    /******************************************************* 実行結果
    befor function           en=10
    
    befor n++  sn= 0  an= 0  en=10
    after n++  sn= 1  an= 1  en=11
    
    befor n++  sn= 1  an= 0  en=11
    after n++  sn= 2  an= 1  en=12
    
    befor n++  sn= 2  an= 0  en=12
    after n++  sn= 3  an= 1  en=13
    
    after function           en=13
    ****************************************************************/
  2. ファイル有効範囲とブロック有効範囲
    #include <stdio.h>
    
    int   fn = 0;       /* File Scope */
    void  inc_n(void);
    void  dec_n(void);
    
    main(){
      printf("befor function            fn=%2d\n\n",fn);
      inc_n();
      dec_n();
      dec_n();
      inc_n();
      printf("after function            fn=%2d\n\n",fn);
    }
    
    void inc_n(void){
      static  int bn = 0;    /* Block Scope */
    
      printf("  befor n++        bn=%2d  fn=%2d\n",bn,fn);
      bn++;
      fn++;
      printf("  after n++        bn=%2d  fn=%2d\n\n",bn,fn);
    }
    
    void dec_n(void){
      static  int bn = 0;    /* Block Scope */
    
      printf("  befor n--        bn=%2d  fn=%2d\n",bn,fn);
      bn--;
      fn--;
      printf("  after n--        bn=%2d  fn=%2d\n\n",bn,fn);
    }
    
    /******************************************************* 実行結果
    befor function            fn= 0
    
      befor n++        bn= 0  fn= 0
      after n++        bn= 1  fn= 1
    
      befor n--        bn= 0  fn= 1
      after n--        bn=-1  fn= 0
    
      befor n--        bn=-1  fn= 0
      after n--        bn=-2  fn=-1
    
      befor n++        bn= 1  fn=-1
      after n++        bn= 2  fn= 0
    
    after function            fn= 0
    ****************************************************************/
  3. 有効範囲の入れ子
    #include <stdio.h>
    
    int   n = 0;
    void  inc_n(void);
    
    main(){
      printf("befor function            n=%2d\n\n",n);
      inc_n();
      printf("after function            n=%2d\n",n);
    }
    
    void inc_n(void){
      static  int n = 10;
    
      printf("  befor n++               n=%2d\n",n);
      {
        int  n=20;
        printf("        in block          n=%2d\n",n);
      }
      n++;
      printf("  after n++               n=%2d\n\n",n);
    }
    
    /******************************************************* 実行結果
    befor function            n= 0
    
      befor n++               n=10
            in block          n=20
      after n++               n=11
    
    after function            n= 0
    ****************************************************************/

構造化プログラミング

  1. 3つの基本処理
    1. 順次処理:上から下へ記述された順に処理を実行する。
    2. 選択・判断処理:条件により実行する処理を選択する。
    3. 反復・繰り返し処理:処理を繰り返して実行する。
  2. モジュール化:複雑なプログラムを設計するとき、まとまって意味のある処理機能ごとにプログラムを分割し、モジュール化を行う。
    1. 処理のまとまりを的確に把握する。
    2. 各モジュールはできるだけ独立したものにする。
    3. 各モジュールはできるだけ汎用性の高いものにする。
    4. 1つのモジュールは全体を見渡せる大きさにする。

識別子(変数、関数等)の結合(linkage)

外部結合と内部結合のサンプルプログラム

  1. ファイル#1
    #include <stdio.h>
    
    int   en = 10;
    void  inc_n(void);
    void  dec_n(void);
    
    main(){
      printf("befor function      en=%2d\n\n",en);
      inc_n();
      printf("\n");
      dec_n();
      printf("\n");
      inc_n();
      printf("\n");
      printf("after function      en=%2d\n",en);
    
      return(0);
    }
  2. ファイル#2
    #include <stdio.h>
    
    extern int en;
    
    void dec_n(void){
      printf(" in dec_n function  en=%2d\n",en);
      en--;
      printf(" in dec_n function  en=%2d\n",en);
    }
  3. ファイル#3
    #include <stdio.h>
    
    static int en=20;
    
    void inc_n(void){
      printf(" in inc_n function         en=%2d\n",en);
      en++;
      printf(" in inc_n function         en=%2d\n",en);
    }
  4. 実行結果
    befor function      en=10
    
     in inc_n function         en=20
     in inc_n function         en=21
    
     in dec_n function  en=10
     in dec_n function  en= 9
    
     in inc_n function         en=21
     in inc_n function         en=22
    
    after function      en= 9

Report#4

 次のプログラムは外部変数に定義され、初期化された10個のint型データの平均を求め、各データと平均との差を表示するプログラムである。
 このプログラムを以下のような関数の翻訳単位にファイルを分け、同様な動作をするプログラムを作成せよ。

関数名引数・パラメータ機能戻り値
floatget_aveなし平均値を求め表示平均値
voidprint_data配列の添字、平均値1つのデータと平均値との差を求め表示なし
  1. プログラム
    /*
      program   : average.c
      comments  : 結合(linkage)を用いて、平均・差を求める。
    */
    
    #include <stdio.h>
    
    int score[10]={3,5,8,9,10,6,7,9,8,3};
    
    int main(){
      int   i;
      float ave = 0.0, dif;
    
      for(i=0; i<10; i++) ave = ave + (float)score[i];
      ave = ave / 10.0;
      printf("ave = %3.1f\n",ave);
      
      for(i=0; i<10; i++){
        dif = score[i] - ave;
        printf("score[%02d]=%2d  Difference from average = %4.1f\n",i,score[i],dif);
      }
      
      return(0);
    }
  2. 実行結果
    ave = 6.8
    score[00]= 3  Difference from average = -3.8
    score[01]= 5  Difference from average = -1.8
    score[02]= 8  Difference from average =  1.2
    score[03]= 9  Difference from average =  2.2
    score[04]=10  Difference from average =  3.2
    score[05]= 6  Difference from average = -0.8
    score[06]= 7  Difference from average =  0.2
    score[07]= 9  Difference from average =  2.2
    score[08]= 8  Difference from average =  1.2
    score[09]= 3  Difference from average = -3.8

考察事項



トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS