16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++Advent Calendar 2018

Day 10

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

Last updated at Posted at 2018-12-09

前日の記事:@niinaさんの「C++しか書かずにPythonライブラリを作る」
翌日の記事:@kizulさんです。

#この記事の概要

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

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

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

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

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

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

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

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

#出力(引数なし)

###C

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

int main(void) {

	puts("Hello, World!");

	return 0;
}
printfを使う場合
#include <stdio.h>

int main(void) {

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

	return 0;
}

###C++

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

int main() {

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

	return 0;
}
std⸬printf (Better C)
#include <cstdio>

int main() {

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

	return 0;
}
std⸬cout
#include <iostream>

int main() {

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

	return 0;
}

###出力結果

Hello, World!

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

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

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

#出力(引数あり)

###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++

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;
}
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

#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++

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

int main() {

	int a;

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

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

	return 0;
}
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マクロを書かないとコンパイルエラーが出ます。

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名前空間に属していないので注意。

VS2017
#include <stdio.h>

int main(void) {

	int a;

	scanf_s("%d", &a);

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

	return 0;
}

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

#乱数(範囲指定なし)

###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++

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

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

int main(void) {

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

	return 0;
}

###C++

constexpr
#include <cstdio>
constexpr int INT_TEN = 10;

int main() {

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

	return 0;
}

###出力結果

10

#配列

###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++

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)

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++

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 さんからのコードを拝借致しました。

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)

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++

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");
}
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

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++

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;
}
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

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++

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;
}
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は忘れてスマートポインタを使いましょう。

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スマートポインタ入門を読んでください。

###出力結果

0 1 2 3 4 5 6 7 8 9

#文字列代入

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

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

int main(void) {

	char str[100];

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

	return 0;
}

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

###C++

std⸬string
#include <iostream>
#include <string>

int main() {

	std::string str;

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

	return 0;
}

###出力結果

abcdefghijk

#文字列連結

###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++

std⸬string
#include <iostream>
#include <string>

int main() {

	std::string str;

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

	return 0;
}

###出力結果

abcdefghijkABCDEFGHIJK

#関数ポインタ

###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++

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;
}
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

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

16
19
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?