C言語/基礎知識

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動


文字入力についての注意[編集]

C言語における文字入力について、下記のことに注意する必要がある。

  • C言語のプログラムは、主に半角英数記号を使って記述されます。(なお、ウィンドウズでプログラム文を文字入力するときは、直接入力モードで入力すること。)
  • 大文字と小文字は厳密に区別され、異なる文字として扱われます。


main関数[編集]

main関数はプログラムの開始処理において、ランタイムライブラリの初期化処理の後、最初に呼び出されるユーザープログラムのエントリーポイントです[1]。 main() は、引数を省略することはできますが、戻値は int とされ環境に実行状況を返し、0 が成功、0 以外が失敗を表します。 この本の多くの例で、main() が戻値を返していませんが、return 0; と明示的に成功したことを返すべきです。

main関数は、次のように記述します。

int main(void)
{
	/*いくつかの文*/
	return 0;
}

「/*いくつかの文*/」の部分に実行したい文を記述します。

例えば、下記のように、記述します。

(記述例)

#include <stdio.h>

int main(void)
{
  int a = 3;

  printf("%d", a);
  return 0;
}

このプログラムの内容については、あとで説明します。とりあえず、このように書くことを、知ってもらいたい。

また、宣言文と式文の文末は、「;(セミコロン)」で終わります(終端記号)。プログラムの実行順序は、基本的に、上から下へ順番に実行されます。


なお、プログラム中で式を書くとき、int a = 3;のように、空白文字(スペース、タブ、改行)スペースを入れても良い。

(記述例)

#include <stdio.h>

int main(void)
{
  int a = 3;

  printf("%d", a);
  return 0;
}


データ型と変数の基本[編集]

変数とは、数値などのデータをひとつ入れるための領域のことです。

C言語では、基本的に、1つの変数には、1つのデータしか入れられません。

変数の宣言[編集]

変数を使用するには、前もって、変数の使用を宣言する必要がある。

とりあえず、手本のプログラムとして

#include <stdio.h>

int main(void)
{
  int a = 3;

  printf("%d", a);
  return 0;
}

というプログラムで、考えよう。

では、解説していこう。

読者の注目先として、上記コードにある、

  int a = 3;

の部分に注目してほしい。

int と宣言したら、intは「整数」という意味であり、その整数iの内容が3であるという意味です。なお、intとは英語で「整数」という意味の英単語 integerインテジャーの略です。intの読むは通常、イントと読むだろう。

なお、もし小数などを宣言したい場合は、intの部分が、他のキーワード(floatやdoubleなど)に変わることになる。

なので、もし

  int a = 3.45;

(×)

のように、整数を宣言したにもかかわらず、宣言された変数に小数の値が入ると、コンパイルなどがエラーになる。

では、C言語では、なぜ、わざわざ整数しか使用できない変数を用意するかというと、1970年代ごろの昔の理由では、メモリの使用量を節約するためであった。

小数データを保存するためには、整数データを保存する場合よりも、メモリの使用量が多くなるのです。


C言語では、「int」 は、整数として宣言したい変数の直前に、つける必要がある。他の多くの言語でも、同様に、変数の前につける事が多い。


上記のコードの「int」のように、これから宣言しようとしている変数についての、データの種類をあらわすための語句のことを「型」(かた)といいます。

「int」は、整数の型を表す。

さて、

  int a = 3;

とは、整数型の使用を宣言しており、その変数の名前は「i」であり、その変数iには3で初期化する、という意味のコードです。


さて、変数宣言と、代入演算子とは、本来は異なる構文要素であるので、

  int a;
  a = 3;

というように、2つの文に分けて記述することもできる。

変数に、なんらかの値を入れることを「代入」といいます。


C言語でいう「変数」は、数学でいう「変数」とは意味が違い、C言語の「変数」には、初期化や代入の前の参照は許されるが値は不定となります。 たとえば、下記のコードはコンパイル時に警告を受け、実行しても望んだ結果が得られないことがあります。

// 警告が出る
#include "stdio.h"

int main(void)
{
    int a; int b; int c;
    c = a + b; // warning: variable 'a' is uninitialized when used here [-Wuninitialized]
    a = 1; b = 5;

    printf("%d\n",c);
	
    return 0;
}

これは、下記のように修正する必要がある。

#include "stdio.h"

int main(void)
{
    int a; int b; int c;
    a = 1; b = 5; // 下の行のcに代入される変数a,bの値を先に確定させる必要がある
    c = a + b; // 代入の時点で値が確定するのでエラーにならない

    printf("%d\n",c);
	
    return 0;
}
表示結果
6

C言語に限らず、他の多くのプログラム言語でも、代入の時点では値が確定していないと警告が出る仕様であるのが通常です。

変数の文字出力[編集]

#include <stdio.h>

int main(void) {
  int a = 3;
  printf("%d", a);
  return 0;
}


これを実行すると場合、「3」が表示されます。

しかし、3の直後に、

3[ユーザー名 ~]$

のように、改行されずに入力カーソルが表示されるので、とても見づらい。(リナックスで、コマンド端末から実行すると、こういう表示になる。)

なので、まず、「3」を表示したあとに改行するように、プログラムを修正しよう。

(改良例)

#include <stdio.h>

int main(void) {
  int a = 3;
  printf("%d\n", a);
  return 0;
}

です。\nは、文字列の中で改行コードを表記するための表記法です。

上記の改良例を実行すると、

3
[ユーザー名 ~]$

のように、「3」のあとに改行されて表示されます。


変数を表示するには、printf関数を使用する必要がある。

ここで気をつける必要があるのだが、C言語のprintf関数の中での二重引用符""の意味は、BASICやその他BASIC派生言語でのprint関数での二重引用符""の使いかたとは、意味が違う。

C言語でのprintf中にある""は、「これから画面に表示を行う」という意味だけを表し、けっして、引用符""内にある文字列「%d」をそのまま画面に表示したりはしません。

なお、「%d」とは、「10進数で表示しろ」という意味のprintf関数の書式指定です。なお、浮動小数点で表示したい場合は、「%f」になる。「%d」や「%f」などを変換指定子といいます。


そして、printf("%d",a);のように、printf関数の形式は、

printf("何進数で表示するか?",どの変数を表示するのか?);

という形式になっている。

printf("%d\n",a);の「,a」のような部分のことを引数(ひきすう)といいます。


変数がいくつもあっても、

#include <stdio.h>

int main(void) {
  int a = 3;
  int n = 7;
  printf("%d\n", n);
  return 0;
}

のように、どの変数を表示すればいいかを、必要に応じて区別できる。

この場合、「7」が表示されます。このように引数で変数名を指定することにより、どの変数を表示するかを、区別できる。

  • 変数名

なお、変数名には、1文字の「n」や、1文字の「d」なども使うことができる。

とはいえ、\nのnと、まぎらわしいので、他の変数に変えるのが良いだろう。


#include <stdio.h>

int main(void) {
  int a = 3;
  int tugi = 8;
  printf("%d\n", tugi);
  return 0;
}
実行結果
8
解説

変数名には、2文字以上の文字も使える。ただし、先端を数字にすることはできません。「1tugi」などの変数名を宣言しようとすると、エラーになり、コンパイルできません。

変数名の最初の文字が、もし数字だと、エラーになる。変数名の最初の文字は、英字または '_' の必要がある。

変数と文字の表示[編集]

コード例
#include <stdio.h>

int main(void) {
  int a = 3;
  int n = 7;
  printf("変数は%dです\n", n);
  return 0;
}
実行例
変数は7です
解説

上記のプログラムのように、printf関数の""には、文字を表記することもでき、その文字が「%d」や「\n」などのキーワードでないかぎりは、そのまま表示します。


コード例
#include <stdio.h>

int main(void) {
  int a = 3;
  int n = 7;
  printf("変数nは%dです\n", n);
  return 0;
}

;実行結果

変数nは7です
解説

この「変数nは」の「n」のように、出力を指定している変数欄と同じ文字があろうが、そのまま「変数nは」表示します。

初心者には、一見すると分かりづらい仕組みかもしれないが、しかし分からなくても気にせず、次の節を読んでください。


複数の変数の表示[編集]

#include <stdio.h>

int main(void) {
  int a = 3;
  int b = 7;
  printf("さいしょの変数は%dです。つぎの変数は%dです。\n", a, b);
  return 0;
}

のようにして、複数の変数を表示できる。

実行結果
さいしょの変数は3です。つぎの変数は7です。


  • 他の例
#include <stdio.h>

int main(void) {
  int a = 3;
  int b = 7;
  printf("変数aは%dです。変数bは%dです。\n", a, b);
  return 0;
}
実行結果
変数aは3です。変数bは7です。


次に、

#include <stdio.h>

int main(void) {
  int a = 3;
  int b = 7;
  printf("さいしょの変数は%dです。つぎの変数は%dです。\n", b, a);
  return 0;
}

のように、printfの出力順序欄にあるaとbの順序を入れ替えみると、・・・

実行結果
さいしょの変数は7です。つぎの変数は3です。

のように、出力結果も、入れ替わっている。


代入式の右辺と左辺[編集]

下記の式の a=a+1のように、右辺と左辺に同じ変数が使われていても、構わません。

#include <stdio.h>

int main(void) {
  int a;  // int型のiという名前の変数を「宣言」します。※図1
  a = 0;  // 0をiに「代入」します。※図2
  printf("いまの変数は%dです。\n", a);
  a = a + 1;  // iの値を「参照」してそれに1を加えたものをiに「代入」する※図3
  printf("この時点の変数は%dです。\n", a);
}
実行結果
いまの変数は0です。
この時点の変数は1です。

となる。

いっぽう「a + 1 = a」(×)とすると、エラーになる。


まとめ[編集]

図1
図2
図3

変数(へんすう)とはデータを格納しておく領域のことです。変数は、ふつうメモリ上に確保され、値を代入したり参照したりすることができる。

変数を使用する手順は以下のとおりです。

  1. 変数の使用を宣言する(宣言と同時に初期値をあたえる事ができ、初期化することは未初期化による不具合を避けるために良い習慣です)
  2. 変数へ値を代入する(scanf関数のようにポインタを介した値の変更も可能です)。
  3. 式中(たとえばprintf関数)で、さきほど代入した変数の値を参照します。

さらに詳しい説明[編集]

変数の宣言[編集]

変数を使用するには前もって宣言をする必要がある。

int a;	//int型のaという名前の変数を「宣言」します。

「int」は変数のデータ型、「a」は変数名です。

変数のデータ型とは、メモリ上に確保する領域のビット長や、確保した領域の扱い方などを決定するものである(型指定子)。データ型は扱いたいデータの種類や値の範囲によって決定します。

「変数名」とはその変数を他の変数と区別するために付ける名前のことで、 変数名に使えるのは、半角英数の小文字と大文字、および_(下線、アンダーライン) です。


たとえば、 下記の文字は変数名に使える。

a
b
c
d
aaa
hensuu
a1
hensuu123

などなど、変数名として使える。


ただし、変数名は、先頭は数字ではダメです。

1a
8hensuu

などは、エラーになる。

日本語文字などの多バイト文字を使用できるかはコンパイラによる。

英数字以外は変数名に用いないのが、安全です。


また、変数名に「int」は使えません。「int」や「return」など、C言語では、すでに使われているので、変数名には利用できません。

このように、変数名に利用できない語句のことを予約語(よやくご)といいます。

予約語の一覧
_Alignas _Atomic _Bool _Complex _Generic _Imaginary _Noreturn _Static_assert _Thread_local alignof auto break case char const continue default do double else enum extern float for goto if inline int long register restrict return short signed sizeof static struct switch typedef union unsigned void volatile while

C言語の予約語には、上記の単語がある。

なお、printfは標準ライブラリ関数で予約語ではありませんが、もしグローバルな変数名に用いてしまうと重複定義となりリンクに失敗する。

初心者が数値の型として使うのは、とりあえず、下記の int, float, double です。

データ型の種類 データ型 データ型の名称 ビット長 扱える値の範囲
整数型 int 整数型 32 -2147483648 ~ 2147483647
浮動小数点型 float 単精度浮動小数点型 32

最小の正の数1.175494351e-38、 最大値3.402823466e+38

double 倍精度浮動小数点型 64 最小の正の数 2.2250738585072014e-308、 最大値 1.7976931348623158e+308
文字型 char 文字型 8 ※ のちのページで後述

実はC言語では、文字を入れるための文字型 char というのもあるのだが、しかし高度な知識が必要なので、あとのページで紹介します。

C言語では、0.333333333333333333333333333・・・ のような無限に桁(けた)のつづく数は、表現できません

C言語で表現できる数値は、すべて、有限の桁(けた)をもつ数です。

コメント[編集]

#include <stdio.h>

int main(void) {
  int a;  // int型のiという名前の変数を「宣言」します。※図1
  a = 0;  // 0をiに「代入」します。※図2
  printf("いまの変数は%dです。\n", a);
  a = a + 1;  // iの値を「参照」してそれに1を加えたものをiに「代入」する※図3
  printf("この時点の変数は%dです。\n", a);
}


「// コメント」のように、//以降にその行の説明を追記できる。このような追記を注釈(ちゅうしゃく)またはコメントといいます。注釈は、機械語には変換されません。

上述のコードでは初心者むけの説明をコメントとして書いているが、実用のプログラムでは、初心者むけの文法はプロは皆知ってるので、プログラムの目的をコメントとして書くほうが望ましい。

例として、下記のようになる、

/* 変数の宣言と代入 */
#include <stdio.h>

int main(void) {
  int a = 0;  // 変数の宣言と同時に初期値を与えると、未初期化による不具合を未然に防ぐことができます。
  printf("いまの変数は%dです。\n", a);
  a = a + 1;
  // 代数学的にありえない表現ですが、変数aの値を1つの増すことになります。
  // このパターンは頻出するので a++ あるいは ++a と書けます。
  // 2つは少し意味が違いますが後に学びましょう。
  printf("この時点の変数は%dです。\n", a);
}


他のコメント記号

コメントの書き方には、「//」の他にも

「/* 変数の宣言と代入 */」

のように、「/*」と「*/」によって、プログラムの説明を追記する方法もあるが、しかしコメントが入れ子になっているとコンパイラが認識しない実装のされてしまっている場合もある(Windows の コンパイラ Visual C++ コンパイラなどでも、時々そういう事も起きる。)。

たとえば

/*
    printf(... );
    /*
        コメントの例
    */
     printf(... );
*/

のように入れ子になっていると、コンパイラが認識しないでエラーになってしまう場合がある。(たとえばコードの動作テストなどで、一部のコードを機能停止したい場合などに、コードの処理の一部をコメントアウトする事があり、その際にコメント記号が入れ子になる場合が多々ある。)


このため、実際のプログラミングのコメントはなるべく、「//」で書いてしまうほうがラクです。

代入[編集]

変数にデータを格納することを「代入」(だいにゅう)と呼ぶ。

a=0;	// 0をaに「代入」します。

上のプロプラムで、「a」は変数名であり、「0」は式です。


「=」は代入演算子と呼ばれ、左辺の変数名が指す変数に、右辺の式の値を代入します。

数学における等号とは、意味の異なる用法であるので注意せよ。

「式」とは定数、変数などを、+(プラス)や-(マイナス)などの演算子(えんざんし)を使って結合したものです。

算術演算子と代入演算子[編集]

+(プラス)や-(マイナス)などを、演算子といいます。

演算子(えんざんし)とは、演算の内容を指示する記号です。


C言語には非常に多くの演算子が存在するが、 ここでは算術演算子と代入演算子についてだけ説明します。

次に算術演算子と代入演算子を使ったプログラムの例を挙げる。

#include <stdio.h>

int main(void) {
  int fu, seki, shou, jouyo, wa, sa;
  fu = -1;
  seki = 2 * 3;
  shou = 6 / 2;
  jouyo = 5 % 3;
  wa = 3 + 6;
  sa = 8 - 2;

  printf("負は%d \n", fu);
  printf("商は%d \n", shou);
}

;実行結果

負は-1
商は3


上記のプログラム中の「=」が代入演算子です。上記のプログラム中で、算術演算子になるものは、「-」「*」「/」「%」「+」「-」です。

【下の表を参照しつつ読むこと】

算術演算子とは、加減乗除などの算術を指示する演算子です。

算術演算子には、加法を指示する+、減法を指示する-、乗法を指示する*、除法を指示する/、剰余を指示する%、などがあり、 また、-は符号の反転を指示するためにも用いられます。

数学と同様に、加減よりも乗除のほうが優先度が高く、 ()で囲むことにより、カッコ内の演算を優先させることができる。


代入演算子とは代入を指示する演算子です。

代入演算子には右辺の値を左辺が指す変数へそのまま代入するように指示する=がある。

  • 次に算術演算子と代入演算子を表にまとめた。
演算子の種類 演算子 演算子の名称 意味
単項演算子 - 単項-演算子 右オペランドの符号を反転した値
乗除演算子 * 2項*演算子 左右オペランドの積
/ 2項/演算子 左オペランドを右オペランドで除した商
右オペランドの値は0以外でなければならません。
左右オペランドが整数型の場合、商の小数部は切り捨てられます。
% 2項%演算子 左オペランドを右オペランドで除した剰余
右オペランドの値は0以外でなければならません。
左右オペランドは整数型でなければならません。
加減演算子 + 2項+演算子 左右オペランドの和
- 2項-演算子 左オペランドから右オペランドを引いた差
代入演算子 = 単純代入演算子 左オペランドが指す変数に右オペランドの値を格納する

※ この表の演算子の種類は、演算子の優先順位が高い順番に並んでいる。

整数どうしの割り算[編集]

#include <stdio.h>

int main(void) {
  int a, b;
  float c;
  a = 8;
  b = 5;
  c = a / b;

  printf("計算結果は%f \n", c);
}


実行結果
計算結果は1.000000

と表示されます。「1.6」とは表示されません。

これは、整数どうしの割り算の結果は整数型として処理されるので、小数点以降が切り捨てられるためです。

(なお、プログラム中の「計算結果は」の後ろは「%f」(浮動小数点)にすることに注意してください。)


#include <stdio.h>

int main(void) {
  int a, b;
  float c;
  a = 8;
  b = 5;
  c = (float)a / b;

  printf("計算結果は%f \n", c);
}
実行結果
計算結果は1.600000

代入計算のさい、「(float)」のように型を明示することにより、整数切り捨てをさせないようにできます。

参照[編集]

変数に格納されたデータを使用することを参照と呼ぶ。 変数は、式の中で参照することができる。

a=a+1;	// aの値を「参照」してそれに1を加えたものをaに「代入」する

参照する際、変数があらかじめ初期化や代入されているよう注意せよ。

変数名の命名時における注意[編集]

このページでは、説明の簡略化の都合で、変数名を「a」や「b」などの短い変数名にした。

だが、実務では、変数の命名の際、1文字の変数の命名は避けるべきです。変数名の命名の際には、ある程度の長さのある変数名をつけるべきです。

なぜなら、もし1文字の変数名だと、たとえばソースコードの修正などで、ソースコード内で変数の文字列の検索をしたい際に、変数以外のものもヒットしてしまい、もはや検索にならないからです。

つまり、ある程度の規模の大きいプログラムの記述になると、もはや1文字だけを検索しても、変数以外の語句の一部も検索されてしまう。なので、たった1文字の変数名の命名は、実務では避けたほうが良い。


仮に作っておいた変数名を、あとから変更する場合があるので、そのような事も見越して、最初の仮の段階から、やや長めの名前を変数名につけておくと便利です。


市販の入門書には、変数名として「a」や「b」などの1文字の短い変数名がつけられているが、

しかし、もしアナタが今後プログラミングに慣れてきたら、命名する変数名は長めにしたほうが良い。

C言語にかぎらず他のプログラミング言語でも同様に、変数名はなるべく、コード内の検索の際に適格にヒットしやすいようにするため、やや長めの変数名にしたほうが良い。

また、あとの単元になるが、「関数」(という機能がC言語にはある)の命名も同様であり、関数の名前もやや長めにするほうが安全です。

定数[編集]

定数とは、プログラム実行時に一定の値しかもたない数です。 変数の値がプログラム実行中に変更される場合もあるのに対して、 定数の値はプログラム実行中を通して一定です。 ソースコード中で直接に記述された定数を特にリテラルとも呼ぶ。 ここではそのリテラルについて説明します。

次に整数定数を使ったプログラムの例を挙げる。

int main(void) {
  int a;
  a = 0;      // 整数定数0をiに代入します。
  a = a + 1;  // aの値に整数定数1を加える。
}

なお、これは画面に何も表示することなく、ただちに終了するプログラムです。 このソースコード中の「0」や「1」が定数です。

【下の表を参照しつつ読むこと】 定数には整数定数、浮動小数点定数、文字定数、文字列定数、などがある。 整数定数とは整数を記述するための定数で、主に10進数表記が使われます。 浮動小数点定数とは浮動小数点数を記述するための定数で、主に10進数の小数点数表記で記述します。 文字定数とは1バイト文字を記述するための定数で、文字を「'(一重引用符)」で囲む。 文字列定数とは1バイト文字または多バイト文字の文字列を記述するための定数で、文字列を「"(二重引用符)」で囲む。

  • 次に主な定数を表にまとめた。
定数の種類 進数 記法
整数定数 10進数 10進数 1234
浮動小数点定数 10進数 10進整数部と「.」と10進小数部 3.14
文字定数 - 「'(一重引用符)」で囲まれた文字 'a'
文字列定数 - 「"(二重引用符)」で囲まれた文字列 "Hello, World!"

標準ライブラリ[編集]

標準ライブラリとは、プログラミングでよく使われる処理がまとめられたもので、 代表的なものには、入出力(stdio.h)、文字列操作(string.h)、数学(math.h)などがある。

「stdio」はスタンダードアイオーの略です。スタンダードアイオーとは、standard input-output スタンダードインプットアウトプットの略です。

スタジオではないので、間違えないように。

しかし、入力と出力とを行うことはプログラミングの初期においても必須なものであるため、入出力(stdio.h)の内、printf関数(プリントエフ)とscanf関数(スキャンエフ)とについては、ここでその使い方を簡単に説明します。

前処理指令[編集]

前処理とは、翻訳単位の翻訳の前に行う処理で、前処理指令とは、#前処理字句で始まる1行を指す。前処理指令には、ソースファイルの1部分を条件によって読み飛ばしたり、他のソースファイルを組み込んだり、マクロを置き換えたりする、などがある。

主にソースファイルの宣言部分をまとめて、他のファイルから使いやすくしたものをヘッダファイルと呼ぶ。

標準ライブラリを使用するためには、使用する標準ライブラリに応じたヘッダファイルを組み込む必要がある。 ヘッダファイルを組み込むには前処理指令の内の1つである#include指令を用いる。 printf関数及びscanf関数を使用するためには、stdio.hというヘッダファイルを組み込む必要がある。 stdio.hを組み込むためには、ソースファイルの先頭で、次のように記述します。

#include <stdio.h>

printf関数[編集]

printf関数(プリントエフ関数)とは、書式付の文章を、標準出力へ書き込む関数です。 標準出力はデフォルトでコンソール画面です。 printf関数の記述は次のようになっている。

printf(書式付の文字列定数, 任意個数の実引数...);

書式付の文字列定数には、それに続く任意個数の実引数と同じ数だけの変換指定が含まれなければならません。 書式付の文字列定数に含まれる変換指定の部分が、それに対応する後の実引数の値によって置換されます。

変換指定は、実引数のデータ型に応じて、主に以下のようになる。

実引数のデータ型 変換指定
int
(整数)
%d
double
(浮動小数点数)
%f
char
(文字)
%c
char*
(文字列)
%s

逆斜線表記[編集]

書式付きの文字列定数には、逆斜線表記(エスケープシーケンス)を含めることもできる。 逆斜線表記とは、\に文字が続くことで特別な意味を表すものです。 主に以下のような逆斜線表記がある。

逆斜線表記 意味
\n 改行(New line)
現在の印字位置を次の行の先頭位置に移動する
\t タブ(horizontal Tab)
次の水平タブ位置に移動する
\' シングルクォーテーション(single quotation mark)
一重引用符
\" ダブルクォーテーション(double quotation mark)
二重引用符
\\ 円記号(\)

printf関数の使用例[編集]

//例 printf関数を用いて変数を出力に書き込む。
#include <stdio.h>

int main(void) {
  int i = 1234;
  printf("iの値は%d\n", i);  //「iの値は1234(改行)」と出力します。
  double d = 3.14;
  printf("dの値は%f\n", d);  //「dの値は3.14(改行)」と出力します。
  char c = 'a';
  printf("cの値は%c\n", c);  //「cの値はa(改行)」と出力します。
  char str[] = "Hello, World!";
  printf("strの値は%s\n", str);  //「strの値はHello, World!(改行)」と出力します。
}

scanf関数[編集]

scanf関数(スキャンエフ関数)を使うことにより、キーボード(標準入力)から入力した数値を、読み取らせることができます。

#include <stdio.h>

int main(void) {
  int input = -1; // scanf() が失敗した場合の対策
  printf("整数を入力してください。\n");
  scanf("%d", &input);
  printf("入力された整数は%dです。 \n", input);

  return 0;
}

これを実行すると、まず

整数を入力してください。

と表示されます。

そして、カーソルが点滅するので、そこに整数を入れて、エンターキー(リターンキー)を押す。 たとえば整数 73 を入れると、

整数を入力してください。
73
入力された整数は73です。

と表示されます。

scanfの使用では、「&input」のように、変数名の前に「&」をつける必要がある。なお、この「&」記号は、記憶領域のアドレスという意味を表す。

アドレスについては、高度な説明になるので、ほかのページで後述します。


「なんで変数へのキーボードからの入力のさい、アドレスというものを使うのか?」という疑問には、

左辺値式を関数の引数に渡す方法が他にない。

という答えになります。

左辺値式は代入の左辺になりうる式の事で、a = 1aが左辺値式です。 他方、関数の引数は値渡しされるので、変数の値を渡すことはできますが、仮引数を変更して元々の変数の値は変わりません。 このため、アドレスを引数として渡し関数の中でアドレス間接で値を書き変えることを実現しています。

#include <stdio.h>

void by_value(int i)
{
    i = 0;
}

void by_address(int *i)
{
    *i = 100;
}

int main(void) {
    int i = 10;
    printf("i = %d\n", i);
    by_value(i);
    printf("by_value(i); i = %d\n", i);
    by_address(&i);
    printf("by_address(&i); i = %d\n", i);
    return 0;
}

結果

i = 10
by_value(i); i = 10
by_address(&i); i = 100

scanf関数の使用例[編集]

//例 scanf関数を用いて入力を変数に読み込む。
#include <stdio.h>

int main(void) {
  int i;
  scanf("%d", &i);  //整数入力をiに格納します。
  double d;
  scanf("%f", &d);  //浮動小数点数入力をdに格納します。
  char c;
  scanf(" %c", &c);  //文字入力をcに格納します。
  char str[32];
  scanf("%31s", str);  //文字列入力をstrに格納します。
}

scanf関数の実用には様々な問題を解決する必要があるが、ここではこれ以上説明しません。 詳細はについてはC言語/標準ライブラリ/入出力#fscanf関数を参照して下さい。


scanfのくわしい説明[編集]

scanf関数の記述は次のようになっている。

scanf(書式付の文字列定数, 任意個数の実引数...);

書式付の文字列定数には、それに続く任意個数の実引数と同じ数だけの変換指定が含まれなければならません。 標準入力からの入力が、書式付の文字列定数に含まれる変換指定に従って、それに対応する後の実引数が指す変数に代入されます。

実引数のデータ型に応じて主に以下のような変換指定がある。

実引数のデータ型 変換指定
int 整数 %d
double 浮動小数点数 %f
char 文字 %c
char* 文字列 %s

任意個数の実引数では、単項&演算子(アドレス参照演算子)を用いて、次のように記述します。

&変数の識別子

これはscanf関数の内部で、この変数の識別子が指すインスタンスに代入するために必要な記述です。 単項&演算子については、ここではこれ以上説明しません。

脚注[編集]

  1. ^ ただし、自立実行環境(例えば組み込み用途)では、main() を用意しない場合もあります。

参考文献[編集]

  • 日本工業標準調査会『JISX3010 プログラム言語C』2003年12月20日改正