読者です 読者をやめる 読者になる 読者になる

paiza開発日誌

paiza(https://paiza.jp ギノ株式会社)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

変数からポインタまで、5分でわかるC言語入門(C11対応版)

f:id:paiza:20170124181039p:plain

f:id:paiza:20151217152725j:plainこんにちは、吉岡(@)です。

Java, C#, C++Objective-C, Ruby, Python, JavaScript, Java, Swift…などなど、現在は非常に多くのプログラミング言語が使われていますが、多数の言語の源流となっているのがC言語です。

もともとC言語は、LinuxMac OS Xの源流となるUNIXの開発のために作られた言語で、今でもLinuxC言語で書かれていますし、多くのOSがCやC++で開発されています。

さらに、C言語はコンピュータを直接操作することに向いているため、組み込みやIoT(Arduino, mbed等)などの用途でも広く使われています。

C言語の文法は、多くのプログラミング言語の文法に影響を与えています。

名前にCが含まれているC++C#Objective-Cはもちろん、Java, JavaScriptとも文法が非常に似ていますし、構造としては、RubyPython、Swiftなどの手続き型言語とも似ている部分が多いです。

また、これらのプログラミング言語自身がC言語で書かれている場合も多く、C言語と同時に利用できる言語も多いです。

C言語は1972年頃に開発された歴史のある言語で、現代のプログラミング言語に比べると機能が限られている部分もありますが、逆に歴史がある分C言語は学習するのに向いているとも言えます

C言語自身、互換性をほぼ保ちながら改善が続いており、最新規格は2011年に公開されたC11となります。現在、ほとんどの開発環境はこのC11に対応しています。

ここでは、最新の仕様(C11)に従ったC言語の基本を5分でわかるように簡単にまとめてみます。

目次

C言語の開発方法

C言語のプログラムは、そのまま実行することはできません。実行するにはコンパイルを行い、実行ファイルに変換する必要があります。

通常、コンパイラや開発環境は別途インストールする必要があります。

ここでは、C言語自体の学習が目的ですので、環境設定の必要がなく、ウェブ上からプログラムを実行できるpaiza.IOを利用します。

プログラミング言語として「C」を選択し、プログラムを入力後、「実行」ボタンを押すと、実行結果が出力エリアに表示されます。

f:id:paiza:20170124181845p:plain Web-based online coding environment | paiza.IO

はじめてのC言語プログラム

それではC言語プログラムを書いてみましょう。

まずは、"Hello World"を表示するプログラムです。

以下のように書いて見ましょう。

“printf(メッセージ)"がメッセージを表示する、肝心の部分です。

他の部分は、とりあえず今はおまじないと思っておきましょう。

hello.c :

#include <stdio.h>
#include <stdlib.h>

int main(){
  printf("Hello World\n");
  return 0;
}

書いたプログラムをコンパイル・実行してみると、"Hello World"と表示されました。

もし表示されない場合は、エラーメッセージを確認してみましょう。

Hello World

変数

上の"Hello World"のように直接表示する文を書くこともできますが、繰り返して利用したり、足し算などの結果を保存を保存するためには、変数を使います。

変数には名前(変数名)をつけておきます。

f:id:paiza:20170123172104p:plain

変数は使う前に宣言する必要があります。C言語では値の種類(型)によって宣言方法が違い、以下のようになります。

数字には、小数を使わない整数型と、小数を使える実数型があります。

整数(0, 1, 2, 3, -1, -2など)には"int"(整数型)を使います。

整数型の"i"という名前の変数は以下のようになります。

int i;

実数(0.1, 100.5, -12.3など)は"double"(実数型)を使います。

double d;

文字(‘a’, ‘b’, ‘c’…)は"char"(文字型)を使います。

文字型は、一重引用符(‘’)で囲って表し、一文字のみ表せることに注意してださい。

char c;

それでは、変数を宣言して表示してみましょう。

変数に数字などの値を設定することを代入といい、"i = 1"と書くと、iには1が設定されます。

変数を参照する場合は、単純に"i"と書きます。

数字を表示するには、「printf(“%d”, i)」のように"%d"を使って表示します。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i;
  i = 1;
  printf("i=%d\n", i);
  return 0;
}

ここで、"int i", “i=1"は、まとめて"int i = 1"と書くこともできます。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i = 1;
  printf("i=%d\n", i);
  return 0;
}

実数(double)の表示には、"%lf"を使います。

#include <stdio.h>
#include <stdlib.h>

int main(){
  double d = 123.456;
  printf("d=%lf\n", d);
  return 0;
}

文字(char)の表示には、"%c"を使います。

#include <stdio.h>
#include <stdlib.h>

int main(){
  char c = 'a';
  printf("c=%c\n", c);
  return 0;
}

“printf"では複数の値を表示することもできます。”%d", “%lf”, “%c"などをprintfの最初の部分(引数)に書き、後の部分(引数)に対応する値を書きます。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int    i = 1;
  double d = 123.456;
  char   c = 'a';
  printf("i=%d, d=%lf, c=%c\n", i, d, c);
  return 0;
}

演算

C言語では、足し算などの計算ができます。(当然ですが・・・)

普通の数式と同じように書けます。

printf("10 * 10 = %d\n", 10 * 10);

変数で計算を行った後に同じ変数に代入することもできます。

iに1を加える場合、以下のように書きます。

i = i + 1;

これは、以下のようにも書けます。

i += 1;
i++;

iを1減らす場合は以下のように書きます。

i = i - 1;
i -= 1;
i--;

コメント

プログラムとして実行しない説明などのコメントは、「//」「/ /」を使います。「// コメント」は一行のコメントに、「/ コメント /」は複数行のコメントに使います。

// 一行コメント
/*
  複数行コメント
  複数行コメント
*/

条件文(if)

変数の値によって処理をわける場合などは条件文を使います。

f:id:paiza:20170123172705p:plain

条件文は"if(条件式){}“と書き、条件式を満たした場合にブロック(”{}“)が実行されます。

条件式では、例えば"X==Y"と書くとXとYが等しい場合に条件式が満たされ、ブロックが実行されます。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i = 1;

  if(i==1){
    printf("iは1です\n");
  }
  return 0;
}

条件を満たさない場合の動作を指定するには、if文の後に"else"を指定します。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i = 2;

  if(i==1){
    printf("iは1です\n");
  }else{
    printf("iは1ではありません\n");
  }
  return 0;
}

if/else文を繰り返すと、複数の条件を書くことができます。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i = 3;

  if(i==1){
    printf("iは1です\n");
  }else if(i==2){
    printf("iは2です\n");
  }else{
    printf("iは1でも2でもありません\n");  
  }
  return 0;
}

条件式は以下のような演算が利用できます。

内容
a==b aとbが同じ
a!=b aとbが違う
a < b aがbより小さい
a <= b aがb以下
a > b aがbより大きい
a >= b aがb以上
a && b aとbと両方がtrue
a || b aとbのいずれかがtrue
! a aの否定

配列

f:id:paiza:20170123173021p:plain

値が多くなると、まとめて扱えると便利です。

値を順番に並べたものを配列といいます。

配列を使うには、かっこ(“[]”)を使います。

配列の宣言では、配列の長さを指定します。

整数型(int)で、3つの値を保存できる配列は以下のように書きます。

int apples[3];

配列の中の値(要素)を使うには、配列の中を位置(インデックス)を指定します。

インデックスは0からはじまります。

この場合、1番目の要素は"apple[0]“、2番目の要素は"apple[1]"、3番目(最後)の要素は"apple[2]"となります。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int apples[3];

  apples[0] = 100;
  apples[1] = 110;
  apples[2] = 120;

  printf("apples=%d, %d, %d\n", apples[0], apples[1], apples[2]);
  return 0;
}

配列の宣言と代入はまとめて行うこともできます。

int apples[3] = {100, 110, 120};

この場合、カッコの中の長さを省略することもできます。

int apples[] = {100, 110, 120};

配列の配列(2次元配列)や、配列の配列の配列(3次元配列)を作ることもできます

int plane[10][10];      // 2次元配列
int space[10][10][10];  // 3次元配列

ループ(while, for)

配列の中身を全て表示するときなど、printf文を繰り返すのは大変です。

ループ(while, for)を使えば、動作を繰り返すことができます。

while文では、かっこ(“()”)の中の条件式を満たしている間、繰り返して実行します。

例えば、以下の場合、while文の中を5回実行します。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i = 0;

  while(i<5){
    printf("i=%d\n", i);
    i++;
  }
  return 0;
}

例えば、以下の場合、while文の中を5回実行します。

for文を使えば、同じ繰り返しを簡単に書けます。

for文では、"for(初期化; 条件式; 繰り返し式)“のように書き、初期化を実行後、条件式を満たしている間繰り返します。繰り返しの最後に繰り返し式を実行します。

上のwhile文と同じように5回繰り返すには以下のように書きます。

#include <stdio.h>
#include <stdlib.h>

int main(){
  for(int i=0; i<5; i++){  
    printf("i=%d\n", i);
  }
  return 0;
}

文字列

文字列は"hello"のように書きますが、C言語では文字列型というものはありません。

それでは、文字列はどのように表現するのでしょうか。

C言語では、 文字列は文字を繰り返した配列として表します。配列の最後には、文字の終わりを示すため、ヌル文字(‘\0’)と呼ばれる特殊な文字を追加します。

たとえば、"hello"という文字列は、[‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\n’]という配列としてあらわします。

文字列の宣言するには"char “(文字型の配列)と書きます。

“"の中には、変数に保存する文字列の長さの最大値より1大きい数を設定します。

char s[100];

文字列を表示するにはprintfで"%s"を指定します。

#include <stdio.h>
#include <stdlib.h>

int main(){
  char s[100] = "hello";
  printf("%s\n", s);
  return 0;
}

関数定義

同じ処理を繰り返して利用できるように、処理をまとめられると便利です。

関数を使えば、複数の処理(文)に名前をつけてまとめることができます。

“ppap"という名前の関数を作るには、以下のように宣言します。

int ppap(){
  printf("pen\n");
  printf("pineaplle\n");  
  printf("apple\n");
  printf("pen\n");
}

関数を呼び出すには、「関数名()」と書きます。

#include <stdio.h>
#include <stdlib.h>

int ppap(){
  printf("pen\n");
  printf("pineaplle\n");  
  printf("apple\n");
  printf("pen\n");
}

int main(){
  ppap();
  return 0;
}

よく見ると「main()」も関数と同じ書き方ですね。

実はこのmainも関数です。プログラムを実行すると、最初に"main"という名前の関数が実行されます。

関数は、引数という値をつけて、引数によって動作を変えることができます。

引数は関数名の後のかっこ"()“の中で指定します。

たとえば、1〜nまでの合計を計算するsumという関数を使うには、引数nを使って以下のように書きます。

#include <stdio.h>
#include <stdlib.h>

int sum(n){
  int total = 0;
  for(int i=0; i < n; i++){
    total += i;
  }
  return total;
}

int main(){
  int total = sum(10);
  printf("total=%d\n", total);
  return 0;
}

構造体

配列は単純に値を並べるだけでしたが、複数の値に名前をつけてまとめた構造を作ると便利です。

このような、複数の値に名前をつけてまとめたものを構造体といいます。

構造体を作るには"struct"を使います。

例えば、文字列のモデル名(model)と、整数の製造年(year)を持つ構造体は以下のように宣言します。

struct Car{
  char model[100];
  int  year;
};

構造体の中の値(メンバ)を利用するには、ドット(“.”)を使い、"構造体名.メンバ名"として指定します。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Car{
  char model[100];
  int  year;
};

int main(){
  struct Car a;
  strcpy(a.model, "Voxy"); // copy string
  a.year  = 2007;

  printf("model=%s, year=%d\n", a.model, a.year);
  return 0;
}

なお、構造体を使った変数は以下のように初期値を設定しながら宣言することもできます。

struct Car a = {"Voxy", 2007};

ポインタ

f:id:paiza:20170131154729p:plain

変数は、実際にはコンピュータのメモリに保存されます。

メモリは配列のようなものですので、変数が保存されているメモリ上の位置を、その変数のアドレスと言います。

変数のアドレスを保存した変数のことをポインタといいます。変数の変数といってもいいです。

ポインタを宣言するには、"*“を使います。

整数型のポインタは以下のように書きます。

int *p;

変数のアドレスは"&“を使います。

ポインタpに変数iのアドレスを設定するには以下のように書きます。

int *p;
int i = 10;
p = &i ;

配列の場合、[]をつけずに変数名と書くと、その配列のアドレスを表します。

文字列は文字の配列ですので、文字列はポインタとしてもあらわせます。

char str[100] = "hello";
char *p;
p = str;

ポインタが示す変数は「*ポインタ名」として表します。

引数のポインタが示す変数に値10を設定する関数"set10"は以下のように書きます。

#include <stdio.h>
#include <stdlib.h>

void set10(int *p){
  *p = 10;
}

int main(){
  int i;
  set10(&i);
  printf("i=%d\n", i);
  return 0;
}

入力

キーボードやファイルなど、標準入力から値を読み込むにはscanfを利用します。

scanfはprintfのように"%“で型を指定して読み込みます。

printfと異なり、引数にポインタを使います。

整数を読み込むには以下のようにします。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int i;
  scanf("%d", &i);
  printf("i=%d\n", i);
  return 0;
}

スペース区切りの整数2つを変数n, mに設定するには以下のようになります。

#include <stdio.h>
#include <stdlib.h>

int main(){
  int n, m;
  scanf("%d %d", &n, &m);
  printf("n=%d, m=%d\n", n, m);
  return 0;
}

文字列を読み込むには"%s"を使います。

#include <stdio.h>
#include <stdlib.h>

int main(){
  char str[100];
  scanf("%s", str);
  printf("str=%s\n", str);
  return 0;
}

マクロ

C言語では、マクロを利用して値に名前をつけることもできます。

マクロは変数と異なり書き換えることができませんが、宣言した後、ほとんどどこでも利用できる特徴があります。

たとえば、ONEで1を、HELLOが"hello"をあらわすには以下のように書きます。

#define ONE 1
#define HELLO "hello"
#include <stdio.h>
#include <stdlib.h>

#define ONE 1
#define HELLO "hello"

int main(){
  printf("%d\n", ONE);
  printf("%s\n", HELLO);
  return 0;
}

まとめ

C言語は古くから現在まで幅広く使われている言語ですが、特に最近ではIoTで使われるケースもあります。

C言語はコンピュータの構造に沿ったシンプルな言語ですので、深く勉強することが、プログラム原理の理解にもつながります。またC言語がある程度習得できると、他の言語も理解しやすくなります。

プログラムは、実際に書いて試してみることで理解が深まります。

動画でプログラミングが学べる「paizaラーニング」には、C言語のレッスンもございます。

動画を見ながらブラウザ上でC言語のコードを書いたり、演習問題を解いたりすることで気軽にプログラムを学べます。ぜひお試しください。

paiza.jp C言語入門編(2レッスン) | プログラミング学習ならpaizaラーニング

C言語コースや無料のC#コースなど多数公開中!プログラミング学習動画

f:id:paiza:20160830130051j:plain paizaでは、未経験者でも動画を通してプログラミング等が学べる「paizaラーニング」を公開中です。

C言語の学習動画はもちろんのこと、RubyPythonJavaPHPJavaScriptなどなど……多数のプログラミング言語が学べるレッスンがございます。

また、2017年1月31日から公開となりました「C#入門編」は無料で見放題となっております。

paizaラーニングでは、paizaの人気美少女キャラクター霧島京子(cv:上間江望)が、かわいい声で優しく・楽しく・わかりやすくプログラミングを教えてくれます。「霧島京子による1本3分程度のレッスン動画」に加え、「ブラウザ上でコードを書いて実行できるオンライン実行環境」「複数の練習問題」で、初心者でも無理なくプログラミングを習得することができます。

paiza.jp


paizaではスキルのあるエンジニアがきちんと評価されるようにし、技術を追い続ける事が仕事につながるようにする事で、日本のITエンジニアの地位向上を図っていければと考えています。特にpaizaではWebサービス提供企業などでもとめられる、システム開発力や、テストケースを想定できるかの力(テストコードを書く力)などが問われる問題を出題しています。

テストの結果によりS,A,B,C,D,Eの6段階でランクが分かります。自分のプログラミングスキルを客観的に知りたいという方は是非チャレンジしてみてください。

http://paiza.jp

プログラミング入門講座|paizaラーニング

PHP入門編Ruby入門編Python入門編Java入門編JavaScript入門編C言語入門編C#入門編アルゴリズム入門編