私が気にする100の事象

気にしなければ始まらない。

C言語とC++って何が違うの?

これは修正すべき点がいくつもあるため、近いうちに修正します。(西暦2021年11月27日追記)

こんにちは、プログラミング初心者の「コウちゃん」です。
こんにちは、プログラミングのことなら、お茶の子さいさい、「おちゃっぱちゃん」です。
今回は「C言語C++って何が違うの?」について、やっていきましょう!

CとC++の違い

C言語C++って結局何が違うの?
簡単に言うと、古くなってしまった昔のC言語増築するような形で、 新しく機能をC言語に追加したものが「C++」なんです。
っていうことは、C++C言語の進化版ってこと?
そゆこと

Wikipediaにも書いてあるように、C++は 1983年にベル研究所のコンピュータ科学者のビャーネ・ストロヴストルップが、 C言語の拡張として開発しました。 拡張はクラスの追加に始まり、仮想関数、多重定義、多重継承、 テンプレート、例外処理といった機能がどんどん追加されていきました。

C++C言語の拡張なので、 C言語で書けるソースコードは、 C++でも書けます。 (何気にココ重要!)

C++での入出力関数

コウちゃん、C言語で「Hello World!」って表示するプログラム書ける?
おうおう、それくらい私だって、お茶の子さいさいだぞ。
舐めてもらっちゃ困るな!

#include <stdio.h>

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

ほらよ
そんなに怒らなくても…
そうだね、正解。
これをC++で書くと、どんな感じになるかというと…

#include <iostream>

int main() {
    std::cout << "Hello World!" << std::endl;
    return 0;
}

こうなります。
おお、結構違う

iostreamについて

このiostreamって何?
C言語では文字列を出力するときはprintf、 文字列を入力するときはscanfを使っていたけれど、これを使うにはstdio.h#includeしなければならなかったでしょう?
C++では、文字列を出力するときはcout、 文字列を入力するときはcin を使い、これらを使うときはiostream#includeしなければならないのです。
なるほど

  • C++で入出力関数を使うときはiostream#includeする

coutについて

#include <iostream>

int main() {
    std::cout << "Hello World!\n" << std::endl;
    return 0;
}

先程言ったように、C++で文字列を出力するときは、coutを使います。
coutはcharactor outputの略です。 具体的にcoutの後に<<(左シフト演算子)を書き、その後に表示したい文字列を出力できます。

本来なら<<は左シフト演算子ですが、

C++で出力するときに使われるこの演算子は、

特別に出力演算子や、挿入演算子

またはインサータなどと呼ばれています。

#include <iostream>

int main() {
    std::cout << "Hello" << " " << "World!" << std::endl;
    return 0;
}

複数の文字列を表示したいときも、このように<<演算子を繋げて、書くことができます。

#include <iostream>

int main() {
    std::cout
    << "Melody in the sky" << std::endl
    << std::endl
    << "Raindrops have been falling down from gray colored" << std::endl
    << "sky and now they ran into my heart" << std::endl
    << "This high wall painted black is cutting off all my view" << std::endl
    << "and even blocking sunlight from me" << std::endl
    << std::endl;
    return 0;
}

長い文章を表示するときは、このように複数行に分けて書く手法もあります。
スマホで見ている方は横にして見ると読みやすいと思います。)

さっきからずっとわかんないだけど、このendlはなに?
説明してなかったね。ごめんごめん。
endlを使うと、改行になるのよ。
だから、C++で改行を出力したいときは、endlを使います。

endlのように関数に挿入したり、関数から抽出

したりする値で特別な効果を持つもののことを

マニピュレータといいます。

  • C++で文字列を出力するときはcoutを使う
  • C++で改行を出力するときはendlを使う
  • 出力するときに使う演算子を出力演算子という
  • マニピュレータとは、関数に挿入したり、関数から抽出したりする値で特別な効果を持つもののことである

名前空間について

今更なんだけど、std::coutとかstd::endlstd::っていうのは何?
それは名前空間といって、同じ関数名が衝突しないようにあるんだよ。
どゆことー?
例えば、同じクラスの「伊藤さん」と、B組の「伊藤さん」がいたとします。 すると、「伊藤さん」だけだと、どちらの「伊藤さん」なのか区別がつきません。 そこで「同じクラスの伊藤さん」、「B組の伊藤さん」とそれぞれ呼ぶことで、 混乱しなくて済みました。
プログラミングでも、もし自分でcout関数を作ったとしたら、 stdcout関数と名前がダブってしまうでしょう?

2つ以上の関数名や、変数名が重なっていること

を「衝突する」と表現します。

ここでは「名前空間によって、同じ関数名が

あっても衝突を防ぐ」という話をしています。

だから、stdcoutっていう意味で、std::coutって書いてんだ。
そうです。
ちなみに::のことをスコープ解決演算子といいます。
stdという名前空間はおそらくstandardの略で、そこにはC++が標準で提供している関数やテンプレートがまとまっています。
でもさ、

#include <iostream>

int main() {
    std::cout << "Hello World!" << std::endl;
    std::cout << "Hello World!" << std::endl;
    std::cout << "Hello World!" << std::endl;
    std::cout << "Hello World!" << std::endl;
    std::cout << "Hello World!" << std::endl;
    return 0;
}

これ、毎回stdって書くの大変じゃない?
だいたい間違っても独自のcout関数なんて宣言しないし。
衝突しないように気をつければいいんじゃない?
そうだね。先程のたとえ話でいうと、同じクラスの人同士で「伊藤さん」って言ったら普通「同じクラスの伊藤さん」になるのと同じ感覚だね。
そういうときは、using namespace 名前空間とすることで、その名前空間を省略して使うことができるようになります。

#include <iostream>

using namespace std;

int main() {
    cout << "Hello World!" << endl;
    cout << "Hello World!" << endl;
    cout << "Hello World!" << endl;
    cout << "Hello World!" << endl;
    cout << "Hello World!" << endl;
    return 0;
}

すっきり!

  • 名前空間は、関数などの集合を分割することで衝突の可能性を低減しつつ参照を容易にする概念である。
  • 名前空間を省略するときはusing namespaceを使う

string型について

C言語では文字列を扱うときchar str[]とかchar *strとか宣言してましたね。
しかし、C++にはstring型(文字列型)という便利な型があります。
具体的にどう便利なの?
それはこれから、話していきましょう。

string型の基本的な使い方

#include <iostream>
#include <string>

using namespace std;

int main() {
    string hello = "Hello";
    cout << hello << endl;
}

その前に、string型の基本的な使い方を見ましょう。
上記のプログラムはstring helloで宣言と同時に"Hello"を代入し、coutで表示するプログラムです。
実行結果はこの通り。
なお、string型を使うにはstring#includeする必要があります。

実行結果

Hello

連結できる

#include <iostream>
#include <string>

using namespace std;

int main() {
    string hello = "Hello";
    string world = "World";
    string hello_world = hello + " " + world + "!";
    cout << hello_world << endl;
}

こんなふうに足し算で文字列を連結できます。

実行結果

Hello World!

ね?便利でしょ?
あら、ほんと

string型をconst char*型に変換したいとき

そんなときはconst char* chars = str.c_str();const char*型に変換できます。

char*型をstring型に変換したいとき

逆はもっと簡単。
string str = std::string(chars);とキャストすればstring型に変換できます。

  • C++にはstring型(文字列型)がある
  • string型を使うにはstring#includeする必要がある
  • 足し算で文字列を連結できる
  • const char* chars = str.c_str();const char*型に変換できる
  • string str = std::string(chars);string型に変換できる

cinについて

まだcinについて話してないね!
cinC言語scanfと同じ役割を果たします。

#include <iostream>
#include <string>

using namespace std;

int main() {
    string str = "";
    cin >> str;
    cout << str;
}

cout演算子の向きが逆なので気をつけましょう。

  • 入力関数はcinを使う

最後に

これでCとC++の違いの説明は終わりです。
お疲れ様でした。

ではまた次の機会に!
ばいばい!