C言語とC++の同時比較リファレンス

前日の記事：@niinaさんの[「C++しか書かずにPythonライブラリを作る」](https://qiita.com/niina/items/e4181a1345cbc4021ad5)
翌日の記事：@kizulさんです。

#この記事の概要

この記事は"**C言語**と**C++**の書き方を両方書き表したもの"です。

つまり、
**"C言語とC++版のロゼッタストーンです。"**

>C言語を学んだけど、C++の書き方がわからない…… (39歳 Aさん 主婦)
>C++は書き方わかるけど、C言語がよくわからない……(195歳 Bさん 小学生)
>他にどんな書き方があるのか知りたい！(17歳 Cさん 高校生)

のような口コミが聞こえてきたので、~~(幻聴)~~

今回は**C言語とC++の書き方を同時にまとめました！**

※この記事は入門書レベルの基本事項から書いていきます。

基本的に以下に記載するソースコードは
**`C89`**と**`C++11`**の環境で動作するように書いています。
**`C99`**や**`C++14`**等で動作するソースコードはその都度バージョンを明記します。
※本当は**C99**で動作するプログラムを載せたいところですが、あえて~~カンブリア紀レベルの~~化石である**C89**でも動作するプログラムを載せていきます。(もしかしたら癖でC99を書いてしまっているかもしれません)

間違いや改善点、追加してほしいものなどありましたらコメントでお伝えください。

#出力(引数なし)

###C

```c:putsを使う場合
#include <stdio.h>

int main(void) {

	puts("Hello, World!");

	return 0;
}
```

```c:printfを使う場合
#include <stdio.h>

int main(void) {

	printf("Hello, World!\n");

	return 0;
}
```

###C++

```cpp:std⸬puts (Better C)
#include <cstdio>

int main() {

	std::puts("Hello, World!");

	return 0;
}
```

```cpp:std⸬printf (Better C)
#include <cstdio>

int main() {

	std::printf("Hello, World!\n");

	return 0;
}
```

```cpp:std⸬cout
#include <iostream>

int main() {

	std::cout << "Hello, World!\n";

	return 0;
}
```

###出力結果

```
Hello, World!
```

みんな大好き**~~ハローワーク~~**、
いいえ、**ハローワールド**です。

巷では、10種類以上の言語で**ハローワールド**をしただけで
**"10種類以上の言語を使えます"**と宣言している人もいるとか。

**ハローワールド**だけでもこのように様々な方法で書くことが出来ます。

#出力(引数あり)

###C

```c:printf
#include <stdio.h>

int main(void) {

	int a = 10;
	int b = 5;

	printf("%d + %d = %d\n", a, b, a + b);

	return 0;
}
```

###C++

```cpp:std⸬printf (Better C)
#include <cstdio>

int main() {

	int a = 10;
	int b = 5;

	std::printf("%d + %d = %d\n", a, b, a + b);

	return 0;
}
```

```cpp:std⸬cout
#include <iostream>

int main() {

	int a = 10;
	int b = 5;

	std::cout << a << " + " << b << " = " << a + b << "\n";

	return 0;
}
```

###出力結果

```
10 + 5 = 15
```

足し算結果の出力です。
入門書では前半のページで学ぶと思います。

ここでついに**可変長引数**のありがたみを受けます。

#数値の入力

###C

```c:
#include <stdio.h>

int main(void) {

	int a;

	scanf("%d", &a);

	printf("a==%d", a);

	return 0;
}
```

@yumetodo さんからのコメントより
>ですが、完全に脇道に逸れるとscanfで数値に変換するのは安全ではないのでだめですね。
>ref: https://qiita.com/yumetodo/items/238751b879c09b56234b

###C++

```cpp:std⸬scanf (Better C)
#include <cstdio>

int main() {

	int a;

	std::scanf("%d", &a);

	std::printf("a==%d", a);

	return 0;
}
```

```cpp:std⸬cin
#include <iostream>

int main() {

	int a;

	std::cin >> a;

	std::cout << "a==" << a << "\n";

	return 0;
}
```

###出力結果

```
10
a==10
```

**scanf**は**アレなので**、**C++**を使用している方は**std::cin**をお勧めします。

###余談

**Visual Studio**では、**scanf**があまりにも危険すぎる(?)ため
**`_CRT_SECURE_NO_WARNINGS`マクロ**を書かないと**コンパイルエラー**が出ます。


```c:VS2017
#define _CRT_SECURE_NO_WARNINGS //ここを書かないとエラー！
#include <stdio.h>

int main(void) {

	int a;

	scanf("%d", &a);

	printf("a==%d", a);

	return 0;
}
```

**Visual Studio**では、**`scanf`**ではなく**`scanf_s`**の使用を
推奨しています。
※**scanf_s**はstd名前空間に属していないので注意。

```c:VS2017
#include <stdio.h>

int main(void) {

	int a;

	scanf_s("%d", &a);

	printf("a==%d", a);

	return 0;
}
```

書き換えるの面倒ですね！(本音)

#乱数(範囲指定なし)

###C

```c:rand
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main(void) {

	int i;

	srand((unsigned int)time(NULL));
	
	for (i = 0; i < 10; ++i) {
		printf("%d ", rand());
	}
	printf("\n");

	return 0;
}
```

###C++

```cpp:std⸬mt19937
#include <iostream>
#include <random>

int main() {

	std::mt19937 mt;
	std::random_device rd;

	mt.seed(rd());

	for (int i = 0; i < 10; ++i) {
		std::cout << mt() << " ";
	}
	std::cout << std::endl;

	return 0;
}
```

@yumetodo さんからのコメントより
`C++14`から`std::rand()`と`std::srand()`は`deprecated`
になったようなのでBetter Cの部分は削除しました。

###出力結果

```:rand
2680 12099 12992 1755 4675 11920 23824 19081 19872 32396
```

```:std⸬mt19937
1028496359 321947819 1840655768 2203056587 3403894914 1543972996 2921512719 528846214 2426473444 1679236695
```

※乱数なので出力される数値はほぼ毎回異なります。
(ただし、randの実装方法だと1秒おきに変わる)

#コンパイル時定数とdefineマクロ

###C

```c:#define
#include <stdio.h>
#define INT_TEN (10)

int main(void) {

	printf("%d\n", INT_TEN);

	return 0;
}
```

###C++

```cpp:constexpr
#include <cstdio>
constexpr int INT_TEN = 10;

int main() {

	std::printf("%d\n", INT_TEN);

	return 0;
}
```

###出力結果

```
10
```

#配列

###C

```c:生配列
#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int a[] = { 5,2,8,3,9,1 };
	size_t a_size = sizeof(a) / sizeof(int);

	for (size_t i = 0; i < a_size; ++i) {
		printf("%d ", a[i]);
	}
	printf("\n");
}
```

###C++

```cpp:std⸬array
#include <iostream>
#include <algorithm>
#include <array>

int main() {
	std::array<int, 6> a{ 5,2,8,3,9,1 };

	for (size_t i{}; i < a.size(); ++i) {
		std::cout << a[i] << " ";
	}
	std::cout << std::endl;
}
```

###出力結果

```
5 2 8 3 9 1
```

#ソート(昇順)

###C (C99)

```c:qsort
#include <stdio.h>
#include <stdlib.h>

int qsort_(const void *a, const void *b) {
	return *(int *)a - *(int *)b;
}

int main(void) {
	int a[] = { 5,2,8,3,9,1 };
	size_t a_size = sizeof(a) / sizeof(int);

	qsort(a, a_size, sizeof(int), qsort_);

	for (size_t i = 0; i < a_size; ++i) {
		printf("%d ", a[i]);
	}
	printf("\n");
}
```

###C++

```cpp:std⸬qsort (Better C)
#include <cstdio>
#include <cstdlib>
#include <array>

int main() {
    std::array<int, 6> a{ 5,2,8,3,9,1 };

    std::qsort(a.data(), a.size(), sizeof(int), [](const void *a, const void *b){
        return *reinterpret_cast<const int*>(a) - *reinterpret_cast<const int*>(b);
    });

    for (size_t i{}; i < a.size(); ++i) {
        std::printf("%d ", a[i]);
    }
    std::printf("\n");
}
```

コメントより @yumetodo さんからのコードを拝借致しました。

```cpp:std⸬sort
#include <iostream>
#include <algorithm>
#include <array>

int main() {
	std::array<int, 6> a{ 5,2,8,3,9,1 };

	std::sort(a.begin(), a.end());

	for (size_t i{}; i < a.size(); ++i) {
		std::cout << a[i] << " ";
	}
	std::cout << std::endl;
}
```

###出力結果

```
1 2 3 5 8 9
```

#ソート(降順)

###C (C99)

```c:qsort
#include <stdio.h>
#include <stdlib.h>

int qsort_(const void *a, const void *b) {
	return *(int *)b - *(int *)a;
}

int main(void) {
	int a[] = { 5,2,8,3,9,1 };
	size_t a_size = sizeof(a) / sizeof(int);

	qsort(a, a_size, sizeof(int), qsort_);

	for (size_t i = 0; i < a_size; ++i) {
		printf("%d ", a[i]);
	}
	printf("\n");
}
```

###C++

```cpp:std⸬qsort (Better C)
#include <cstdio>
#include <cstdlib>
#include <array>

int main() {
    std::array<int, 6> a{ 5,2,8,3,9,1 };

    std::qsort(a.data(), a.size(), sizeof(int), [](const void *a, const void *b){
        return *reinterpret_cast<const int*>(b) - *reinterpret_cast<const int*>(a);
    });

    for (size_t i{}; i < a.size(); ++i) {
        std::printf("%d ", a[i]);
    }
    std::printf("\n");
}
```

```cpp:std⸬sort
#include <iostream>
#include <algorithm>
#include <array>

int main() {
	std::array<int, 6> a{ 5,2,8,3,9,1 };

	std::sort(a.begin(), a.end(), std::greater<int>());

	for (size_t i{}; i < a.size(); ++i) {
		std::cout << a[i] << " ";
	}
	std::cout << std::endl;
}
```

###出力結果

```
9 8 5 3 2 1
```

#整数型の最大値・最小値

###C

```c:INT_MIN/INT_MAX
#include <stdio.h>
#include <limits.h>

int main(void) {

	int int_min = INT_MIN;
	int int_max = INT_MAX;
	printf("int: %d ~ %d \n", int_min, int_max);

	return 0;
}
```

###C++

```cpp:INT_MIN/INT_MAX (Better C)
#include <cstdio>
#include <climits>

int main(void) {

	constexpr int int_min = INT_MIN;
	constexpr int int_max = INT_MAX;
	std::printf("int: %d ~ %d \n", int_min, int_max);

	return 0;
}
```

```cpp:std⸬numeric_limits
#include <stdio.h>
#include <limits>

int main() {

	constexpr int int_min = std::numeric_limits<int>::min();
	constexpr int int_max = std::numeric_limits<int>::max();
	printf("int: %d ~ %d \n", int_min, int_max);

	return 0;
}
```

###出力結果

```
int: -2147483648 ~ 2147483647
```

#メモリ領域の動的確保

###C

```c:malloc
#include <stdio.h>
#include <stdlib.h>

int main(void) {

	int *m = NULL;
	int i, n = 10;

	m = (int *)malloc(n * sizeof(int));

	for (i = 0; i < n; i++) m[i] = i;
	for (i = 0; i < n; i++) printf("%d ", m[i]);
	printf("\n");

	free(m);
	return 0;
}
```

###C++

```cpp:std⸬malloc (Better C)
#include <cstdio>
#include <cstdlib>

int main() {

	int *m{ nullptr };
	const size_t n{ 10 };

	m = (int *)std::malloc(n * sizeof(int));

	for (size_t i = 0; i < n; i++) m[i] = (int)i;
	for (size_t i = 0; i < n; i++) std::printf("%d ", m[i]);
	std::printf("\n");

	std::free(m);
	return 0;
}
```

```cpp:new(C++11より前向け)
#include <cstdio>

int main() {

	int *m{ nullptr };
	const size_t n{ 10 };

	m = new int[n];

	for (size_t i = 0; i < n; i++) m[i] = (int)i;
	for (size_t i = 0; i < n; i++) std::printf("%d ", m[i]);
	std::printf("\n");

	delete[] m;
	return 0;
}
```

`new`は忘れて`スマートポインタ`を使いましょう。

```cpp:std⸬unique_ptr
#include <cstdio>
#include <memory>

int main() {

	const size_t n{ 10 };
	std::unique_ptr<int[]> m(new int[n]);

	for (size_t i = 0; i < n; i++) m[i] = (int)i;
	for (size_t i = 0; i < n; i++) std::printf("%d ", m[i]);
	std::printf("\n");

	return 0;
}
```

スマートポインタについては
[C++11スマートポインタ入門](https://qiita.com/hmito/items/db3b14917120b285112f)を読んでください。

###出力結果

```
0 1 2 3 4 5 6 7 8 9
```

#文字列代入

###C(文字数がわかっている場合)

```c:strcpy
#include <stdio.h>
#include <string.h>

int main(void) {

	char str[100];

	strcpy(str, "abcdefghijk");
	printf("%s\n", str);

	return 0;
}
```

他のやり方は準備中……。

###C++

```cpp:std⸬string
#include <iostream>
#include <string>

int main() {

	std::string str;

	str = "abcdefghijk";
	std::cout << str << std::endl;

	return 0;
}
```

###出力結果

```
abcdefghijk
```

#文字列連結

###C(文字数がわかっている場合)

```c:strcat
#include <stdio.h>
#include <string.h>

int main(void) {

	char str[100];

	strcpy(str, "abcdefghijk");
	strcat(str, "ABCDEFG");
	printf("%s\n", str);

	return 0;
}
```

他のやり方は準備中……。

###C++

```cpp:std⸬string
#include <iostream>
#include <string>

int main() {

	std::string str;

	str = "abcdefghijk";
	str += "ABCDEFGHIJK";
	std::cout << str << std::endl;

	return 0;
}
```

###出力結果

```
abcdefghijkABCDEFGHIJK
```

#関数ポインタ

###C

```c:Function Pointer
#include <stdio.h>

//加算
int add(int x_, int y_) {
	return (x_ + y_);
}
//減算
int sub(int x_, int y_) {
	return (x_ - y_);
}
//乗算
int mul(int x_, int y_) {
	return (x_ * y_);
}
//除算
int div(int x_, int y_) {
	return (x_ / y_);
}

int main(void) {

	int a = 18;
	int b = 3;
	int ans;
	int(*f)(int, int);

	printf("a = %d, b = %d\n", a, b);

	f = add;
	ans = (*f)(a, b);
	printf("a + b = %d\n", ans);

	f = sub;
	ans = (*f)(a, b);
	printf("a - b = %d\n", ans);

	f = mul;
	ans = (*f)(a, b);
	printf("a * b = %d\n", ans);

	f = div;
	ans = (*f)(a, b);
	printf("a / b = %d\n", ans);

	return 0;
}
```

###C++

```cpp:Function Pointer (Better C)
#include <cstdio>

//加算
int add(const int x_, const int y_) {
	return (x_ + y_);
}
//減算
int sub(const int x_, const int y_) {
	return (x_ - y_);
}
//乗算
int mul(const int x_, const int y_) {
	return (x_ * y_);
}
//除算
int div(const int x_, const int y_) {
	return (x_ / y_);
}

int main() {

	const int a{ 18 };
	const int b{ 3 };
	int ans;
	int(*f)(int, int);

	std::printf("a = %d, b = %d\n", a, b);

	f = add;
	ans = (*f)(a, b);
	std::printf("a + b = %d\n", ans);

	f = sub;
	ans = (*f)(a, b);
	std::printf("a - b = %d\n", ans);

	f = mul;
	ans = (*f)(a, b);
	std::printf("a * b = %d\n", ans);

	f = div;
	ans = (*f)(a, b);
	std::printf("a / b = %d\n", ans);

	return 0;
}
```

```cpp:std⸬function
#include <cstdio>
#include <functional>

//加算
int add(const int x_, const int y_) {
	return (x_ + y_);
}
//減算
int sub(const int x_, const int y_) {
	return (x_ - y_);
}
//乗算
int mul(const int x_, const int y_) {
	return (x_ * y_);
}
//除算
int div_(const int x_, const int y_) {
	return (x_ / y_);
}

int main() {

	const int a{ 18 };
	const int b{ 3 };
	int ans;
	std::function<int(int, int)> f;

	std::printf("a = %d, b = %d\n", a, b);

	f = add;
	ans = f(a, b);
	std::printf("a + b = %d\n", ans);

	f = sub;
	ans = f(a, b);
	std::printf("a - b = %d\n", ans);

	f = mul;
	ans = f(a, b);

	std::printf("a * b = %d\n", ans);

	f = div_;
	ans = f(a, b);
	std::printf("a / b = %d\n", ans);

	return 0;
}
```

###出力結果

```
a = 18, b = 3
a + b = 21
a - b = 15
a * b = 54
a / b = 6
```

##私が記述したソースコードのライセンス

These codes are licensed under CC0.
[![CC0](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

ソースコードは自由に使用してください。