ホーム » スタッフ » 斉藤徹 » 講義録 » 情報構造論 » 型の無い言語からC言語を学ぶと

型の無い言語からC言語を学ぶと

情報構造論の中間試験の採点をしていて気づいたこと。

プログラムが解っていない学生の回答で、関数呼び出しで実引数に int とか実引数の型を書く学生がいる。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
int foo( int x ) {
return x * x ;
}
void main() {
for( int i = 0 ; i < 10 ; i++ )
printf( "%d" , foo( int i ) ) ;
} ~~~ なぜ int を書くの?
int foo( int x ) { return x * x ; } void main() { for( int i = 0 ; i < 10 ; i++ ) printf( "%d" , foo( int i ) ) ; } ~~~ なぜ int を書くの?
int foo( int x ) {
   return x * x ;
}
void main() {
   for( int i = 0 ; i < 10 ; i++ )
      printf( "%d" , foo( int i ) ) ;
}                         ~~~ なぜ int を書くの?

でも、最近の学生はプログラミングで最初に習うプログラム言語が、JavaScript だったり、Python だったりと、型の無い言語であることが多い。

こういう学生さんは、関数宣言と関数呼び出しでは、以下のような感じで習うことだろう。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// JavaScript
function foo( x ) {
return x * x ;
}
for( var i = 0 ; i < 10 ; i++ )
print( foo( i ) ) ;
## Python
def foo( x )
return x * x
for i in range( 0 , 10 )
print( foo( i ) )
// JavaScript function foo( x ) { return x * x ; } for( var i = 0 ; i < 10 ; i++ ) print( foo( i ) ) ; ## Python def foo( x ) return x * x for i in range( 0 , 10 ) print( foo( i ) )
// JavaScript
function foo( x ) {
   return x * x ;
}
for( var i = 0 ; i < 10 ; i++ )
   print( foo( i ) ) ;

## Python
def foo( x )
   return x * x

for i in range( 0 , 10 )
   print( foo( i ) )

んで、こういう学生さんは、関数宣言の仮引数部分を見ると、変数名しか書いてない。この後にC言語を習うと、仮引数の宣言で foo( int x ) みたいに書いてあると、そこに int と書かないとダメみたいに思う、もしくは int x で一つの引数みたいに思うんだろうな。
だから、関数呼び出しの実引数にで、foo( int i ) みたいに型名を書いてしまうと思われる。int というのは、整数型にするためのもの…みたいなイメージなんだろうか?。

C言語での関数宣言と関数呼び出しの説明

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// fooという関数の宣言
int foo( int x ) // foo()の関数の答えの型は、int型。
~~~~~~仮引数
{ // 仮引数 x の型は、int 型。
return x * x ;
}
void main() {
for( int i = 0 ; i < 10 ; i++ )
printf( "%d¥n" , foo( i ) ) ;
~~~実引数
// foo() の第一引数は、整数型を書かないといけない。
// 1番目の実引数 i の型は、int i で宣言されているから、int 型。
// foo( 1.2 ) と書くと、第一引数は double だから、
// 引数の型が合わないのでエラー。
}
// fooという関数の宣言 int foo( int x ) // foo()の関数の答えの型は、int型。 ~~~~~~仮引数 { // 仮引数 x の型は、int 型。 return x * x ; } void main() { for( int i = 0 ; i < 10 ; i++ ) printf( "%d¥n" , foo( i ) ) ; ~~~実引数 // foo() の第一引数は、整数型を書かないといけない。 // 1番目の実引数 i の型は、int i で宣言されているから、int 型。 // foo( 1.2 ) と書くと、第一引数は double だから、 // 引数の型が合わないのでエラー。 }
// fooという関数の宣言
int foo( int x )    // foo()の関数の答えの型は、int型。
         ~~~~~~仮引数
{                   // 仮引数 x の型は、int 型。
   return x * x ;
}
void main() {
   for( int i = 0 ; i < 10 ; i++ )
      printf( "%d¥n" , foo(  i  ) ) ;
                            ~~~実引数
      // foo() の第一引数は、整数型を書かないといけない。
      // 1番目の実引数 i の型は、int i で宣言されているから、int 型。
      // foo( 1.2 ) と書くと、第一引数は double だから、
      // 引数の型が合わないのでエラー。
}

関数宣言の引数は、仮引数と呼ぶ。関数を呼び出すときの引数は、実引数と呼ぶ。
C言語では、関数宣言の仮引数には「型」を明示する必要がある。(というか変数宣言では型を明示しないとダメ)
さらにC言語では関数を呼び出すときに、仮引数と実引数で「型」が一致していないとエラーとなる。

JavaScript や Python では、変数に「型」という概念が不要なので、仮引数宣言には「型」を明示する必要がない。

C言語 や Java は、静的な型付けの言語。最初から型がきまっていないとダメな言語

これに対し、JavaScript や Python という言語は、動的な型付けの言語。プログラム言語が実行中に型を意識しながら動く言語。