質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

6回答

2871閲覧

C++ を学び疑問に思った点を解消して欲しい

u.sayaka0112

総合スコア38

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

3グッド

1クリップ

投稿2020/04/08 15:13

編集2020/04/08 15:20

【背景】

在宅勤務になり自由な時間ができたので c++ を学習し始めました!!
普段は python を使っています。違いが多々あって楽しいです。

基本的な文法をざっと覚えて、かの有名な
AtCoder に登録したら次にやること ~ これだけ解けば十分闘える!過去問精選 10 問 ~
をざっと解いてみました。
いくつか疑問に思った点があり、周りに聞く人もいないので、c++を普段使っている方々にお伺いしたいです。

環境

macOS Catalina 10.15.4
VSCode

【疑問5つ】

1. 出力について

cout << "hoge" << endl;

毎回書くんですか??
python だと print('hoge')で終わるので疲れちゃいます!

2. 「"hoge"」 と 「'hoge'」

シングルクオテーションだとエラーが出てしまうんですが、ダブルクオテーションじゃないとダメなんですか??
ちょっとだけ不便に感じます!!

3. これだけ解ければ〜の3問目より

#include <iostream> using namespace std; # ここ! int N; int A[210]; int main() { cin >> N; for (int i = 0; i < N; ++i) cin >> A[i]; ...

基本的に「これさえ解けば〜」のけんちょんさんのコードを参考にしています。
c++ はまずmain関数が読み込まれてグローバル変数に置かれると学びました。
であるならば int N; intA[210]; は main()の中に書いても良いですよね!!
これがお作法なのか教えて欲しいです。

4. 文末のセミコロン

文末に ; が必要なのは理解しました。JSでもそうですもんね。
エディタは VScode を使っていまして、intellisense機能(自動補完?)の設定を下記記事を参考に行いました。
Visual studio codeで競プロ環境構築[mac OS]

確かにインデント等の修正は行ってくれます。
が、セミコロンを忘れた際に自動で着けてくれないんですか??
毎回忘れちゃいます。ぶっちゃけこのために質問を立てたようなものです。
js では行ってくれるのに。これは私の設定が誤っているんでしょうか。

5. for文等の{}のお作法

# こっちを望む!! for (int i = 0; i < N; ++i){ cout << i << endl; } # 自動補完?でこうなる!! for (int i = 0; i < N; ++i) { cout << i << endl; }

4の質問とも似たものなんですが、intellisense機能で下のように修正されます。
私としては、断然上の方が見やすい!!
お作法的に下の書き方なんでしょうか。慣れですか??

以上、が c++ を学習し初めて2日目の疑問です。
これからまだ出てくると思いますが、さしあたってお伺いしたいです!!
よろしくお願いします!!!!

yumetodo, JunpeiTajima, hayataka2049👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

こんにちは。

PythonとC++は言語の目的がかなり異なるので、違和感を感じるケースがそこそこ多いと思います。
Pythonは軽量プログラミング言語ですが、C++はその対極の言語です。

C++は大規模なプログラムを開発することにフォーカスしています。そのために、できる限りコンパイル時にプログラマのミスを検出できるように設計されています。なので、ちょっとした使い捨てスクリプトやその延長線上にあるようなプログラムを書くのには全く向いていません。

cout << "hoge" << endl;
毎回書くんですか??

はい、そうです。
私は下記のように記述することを好みますし、そのようなC++erも少なくないです。(using namespace std;は意外に好まれないのです。

std::cout << "hoge" << std::end;

ある意味、C++はキータイプを惜しんでは行けない言語なのです。鬼のようにタイプすることも時にはあります。しかし、似たようなことを繰り返し記述するような時、オーバーヘッドなくキータイプ量を減らせる仕組みも多数あります。ただし、オーバーヘッドとタイプ量が両立しないような場合には、タイプ量が増えてもオーバーヘッドを増やさないことを重視するような言語です。

また冒頭にも書いたようにC++はプログラマのミスをできる限り事前に検出できるよう設計されています。しかし、実はバグ検出や回避のためにオーバーヘッドが増えるくらいなら、バグ検出や回避を諦めるような言語でもあります。

シングルクオテーションだとエラーが出てしまうんですが、ダブルクオテーションじゃないとダメなんですか??

はい、その通りです。ダブルクォーテーションは文字列を囲み、シングルクォーテーションは「文字」(1文字だけ)を囲みます。 C++は文字と文字列を厳密に区別することで、ミスを検出しやすくしています。

であるならば int N; intA[210]; は main()の中に書いても良いですよね!!

ご提示されたコードを見る限り、その通りです!!

これがお作法なのか教えて欲しいです。

グローバル変数は使わない方が好ましいという原理原則があります。C/C++に限らず、一般的な原理原則です。ただし「使ってはダメ」という意味ではないです。グローバル変数はバグのリスクが高いので使うメリットとデメリットを慎重に見極めるべきです。使った方が好ましいケースは存在しますが、それを判断できない内は使わないほうがよいかも知れません。

セミコロンを忘れた際に自動で着けてくれないんですか??

セミコロンを勝手に補われると、それが非常に痛いバグになるケースもあるからと思いますが、自動にセミコロンを付けるようなIDEを見たことはないです。

C++

1if (foo) 2 std::cout << "foo\n";

C++

1if (foo); 2 std::cout << "foo\n";

などと勝手に書き換えられたら、ほとんどのプログラマーはそのIDEを投げ捨てるだろうと思います。
C++は、(邪悪とも呼ぶ人もいるマクロを使うことができるので、この例のように自明でないケースも多々あります。

intellisense機能で下のように修正されます。

私としては、断然上の方が見やすい!!
お作法的に下の書き方なんでしょうか。慣れですか??

慣れというか好みですね。また行数でプログラムの価格が決まるケースもあるので、前者を指定する発注者も居るかも知れません。前者の記述をC++でもよく見かけますし、恐らく設定しだいで前者を選択できるだろうと思います。

因みに、私は好き嫌いが激しいので前者は嫌いです。}に対応する{を探しづらいからです。この2つの対応付けを見失うのは非常に痛いので、見栄えが悪くなっても後者を好みます。VS Codeのデフォルトが後者であることを私は喜ばしく感じます。


C++は古くから使われている大規模開発(例えば数百万行とか)が可能な言語です。ですのでC++で記述されている大規模なライブラリやアプリが多数あります。
そしてC++は今も発展を続けています。その際にそれらのプログラムをコンパイルできなくなると無茶苦茶痛いです。
そのため互換性を壊さないように発展しなければならないという非常に辛い制約を抱えています。その結果どうしても一部理不尽な仕様も残っています。
しかし言語仕様の複雑さに比べて多くはないと思います。言語仕様を発展させている超絶天才たちの努力の賜物と思います。(C++は学ぶだけでも超難解なのに互換性を維持しつつ発展させるとか、恐ろしいほどの天才の集まりと思います。)

投稿2020/04/08 16:55

編集2020/04/08 17:09
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u.sayaka0112

2020/04/09 04:21

ご回答いただきありがとうございます! 疑問点に加えて c++ についてもご教授くださり、かつわかりやすいのでベストアンサーに選ばせて頂きました !! 初めて静的型付言語を学んでいて、データ型を予め決めておくのは不便のように感じますが、データ構造を意識するようになったのですごく良い勉強になっています。これからも精進します!!
guest

0

なんか他の方の回答がマイルドなので私も回答することにします。

いやぁ、Pythonを使えるなんてすごいですね。私がPythonでなにか作ろうとすると必ず何かしらのバグを踏んでデバッグするためにpythonをビルドして、原因特定して特定できないかバグレポを投げるかするはめにどういうわけかなるので、pythonはとても難しいです。なんでなんでしょうね。

まあそれはさておき本題ですが

毎回書くんですか??

python だと print('hoge')で終わるので疲れちゃいます!

よその言語で恐縮ですが、JavaだとSystem.out.println(“Hello, world.”);と書くのだそうです。それに比べたら短いと思いませんか?

ちなみにusing namespace std;は百害あって一利もないのでやめましょう。
なぜusing namespace std;を避けるべきか - yumetodoの旅とプログラミングとかの記録
実は先日C++界隈を騒がせてなぜかTwitterのトレンド入りまで果たした、bits/stdc++.hをincludeすることの次くらいにやるべきではないことです。

シングルクオテーションだとエラーが出てしまうんですが、ダブルクオテーションじゃないとダメなんですか??

ちょっとだけ不便に感じます!!

シングルクォーテーションで囲まれたものを「文字リテラル」、ダブルクオーテーションで囲まれたものを「文字列リテラル」と言います。ただここでより重箱の隅をつつく話をするとそもそも「文字」の定義ってなんやねんとなり、C++の、ひいてはコンピュータにおける文字の取り扱いの深い闇に触れることになるでしょう。実はpythonもpyton3になるまで相当いろいろ問題があったらしいです、知らんけど。

c++ はまずmain関数が読み込まれてグローバル変数に置かれると学びました。

そもそもその人のコードに文句を大量につけたいところですが割愛して根本的なお話を。

pythonでもグローバル変数とかそういう概念はあったと思いますが、C++にも似たような概念があります。極めて似通っているのでやっぱり慣習的にグローバル変数とかいっちゃうことが大半ですが、storage(ストレージ)と言います。宣言の場所や仕方によってstorage duration(変数の生存期間)が異なります。詳しくは
C++のメモリーの話とストレージの有効期間の話をしようか - Qiita
をどうぞ。
一般にグローバル変数と言われるものは、関数外に宣言されたstatic storage durationに該当します。これはプログラムの開始と同時、mainの実行の前にに初期化が行われます。そしてstd::exitの呼び出しによって(main関数からのreturnもstd::exitを呼び出したかのように変換されます)破棄されます。

ここまでの長い説明を端折ると、寿命が長いということです。

また、一般にグローバル変数と言われるものは、どこからでもアクセスできるという特徴を持ちます。
つまり、どこで値が書き換わるかわかりにくいということになります。

これは現代、プログラムを書くときに一般によく言われる作法である(C++に限らずpythonでもですよ!)、数多くの原則の前提条件を破壊し、単体テストが困難になるため、避けられる傾向にあります。
もちろんやむを得ない場合もありますが。

文末のセミコロン

formatterはやってくれないかもしれませんが、コンパイラは怒ってくれたりしますので、結果的にIntelliSenseも怒ってくれるでしょう。
https://wandbox.org/permlink/72o4PDCgM9fNXsHO

もっともすでにChronianさんが指摘のとおり、マクロが絡んだりといった複雑なケースでは絶対ではないですが。

そもそもですが、C++の仕様というのはコンパイラを実装するには極めて難解でして、また自由なライセンスで書かれたC++コンパイラであるgccはコードを再利用しにくく作っていたこともあり、clangが登場するまでこうした支援をするツールを作る難易度が極めて高かったという歴史的経緯もあり、ここ数年になってようやく主要な開発環境でどこでも十分な支援を受けられるようになったくらいです。とくにMicrosoftのVSCodeというテキストエディタと、それに端を発するLanguage Server Protocolの果たした貢献は計り知れません。

for文等の{}のお作法

好みの問題ですね。わりとどっちも見かけます。すでにSHOMIさんが回答されているようにclang-format(さっき書いたclangと同じプロジェクトです)の設定をすることでできます。紹介のあるURLにかかれているように.clang-formatファイルを作って設定することで自由に変更できます。
英語ですが多分公式ドキュメントが一番わかり易いと思います。Google翻訳とかを適宜つかって見てください
https://clang.llvm.org/docs/ClangFormatStyleOptions.html

なおC++の複雑さのあまり、clang-formatのバグをよく踏んでしまう人も一定数いるようで、こうしたフォーマッターを使わない人も結構います。私もその一人です。ただ最近はわりと安定しているっぽいし今度設定するかなぁ。

まあJavaScript界隈のESLintやPrettierのようにはなかなかいかないものです。

投稿2020/04/08 17:49

yumetodo

総合スコア5852

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Pythonは(というか後発の言語は)C/C++の「これは俺様の用途にはめんどくさい、いらない儀式だ」というのをいろいろ省いて「便利」になってますから、用途によっては「とっても簡単」になって当たり前です。それがそんなにいいならそっちを使ってね、としかいいようがなく議論になりません。

ただ、C++について「それは違う」というところだけ。

c++ はまずmain関数が読み込まれてグローバル変数に置かれると学びました。

関数がグローバル変数に置かれるって? C/C++では関数はオブジェクトではないので、「変数に置かれ」たりはしません。本当にそう書いてあるのなら、その情報源の信憑性を疑ったほうがいいかも知れません。

であるならば int N; intA[210]; は main()の中に書いても良いですよね!!

(個人的にはこういうところで感嘆符をつけるのは大嫌いですが、それは私のシュミの範囲なので表明だけ。使うなとはいいません)
C/C++では、main関数からプログラムが始まって、main関数が終わることでプログラムが終了します。一方、グローバル変数は「プログラムの開始から終了までが寿命」です。なので、グローバル変数とmain関数のローカル変数は寿命がほぼ一致(大抵は同じと言ってもいいくらい)しています。
そのプログラムであれば、ユーザーがプログラマが期待するものを入力している範囲では同様に動作します。
しかし、寿命はそうであっても、変数の初期値の扱いがグローバル変数とローカル変数で異なるので、場合によってはそれが表面化することもあります。ローカル変数は特に指定しない場合初期値は「不定」(実行してみるまで決められない)です。例えば、質問のプログラムでいきなり'a'とか入力すると、cinでの数値取り込みが失敗するのでNは初期値のままで以降に進みます。グローバル変数の場合は0に初期化されていますが、ローカル変数では100かも、10億かも、あるいは-1かも知れず、どういう動作をするか予期出来ません。

文末に ; が必要なのは理解しました。

文末に;が必要、というのは違います。
文の1つの形態として 式 ; というのがあるのは事実ですが、例えばif文は、if(式)文 というのが構文で、if文自体の終わりに;があるわけではありません。ついでに言えば、if文などでよく使われる、複数の文をまとめて1つの文として扱う「複文」{ 文 文 ... }の最後にも;は付きませんね。
なんでもかんでも「終わりに;をつける」とおぼえてしまうと、初心者にありがちなif(式); 文とかfor( ; ; );文をやっちまうことになります。でも、これは文法的に有効なので...

セミコロンを忘れた際に自動で着けてくれないんですか??

セミコロンの有無で動作が変わってどちらも文法的に正しいという場合、それが付け忘れなのかそうでないのか、どうやって処理系がプログラマの意図を知ることが出来るでしょう?
C/C++はプログラマを信じて(責任丸投げともいう)、プログラマの言う通りに動こうとするのがポリシーです。

for文等の{}のお作法

あくまでお作法なので、諸流派あります。文法的にはC/C++は「フリーフォーマット言語」なので、あなたが一人で書くプログラムならあなたの好きにすればいいです。大抵のフォーマッタはカスタマイズ出来るようになっています。

よろしくお願いします!!!!

ぐふぅ...

投稿2020/04/09 00:48

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ローカル変数ではなくグローバル変数を用いるのは
グローバル変数が

  • ゼロ初期化されるので=0={0}を省く事ができる
  • スタックを消費しないので巨大配列もある程度作れる

という競プロよりはコードゴルフ向けのハックです。

ちなみに私は頭が悪くグローバル変数の管理をやりたくないので
このハックは嫌いです。

投稿2020/04/08 23:01

asm

総合スコア15149

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

cout << "hoge" << endl;

cout << "hoge" ;
では、動作に違いがあり、C++ではその違いをプログラマーが選択できます
(どのように利用するかはその人次第ですが)

pythonだとどうやるんだろうか、考えたこともないが

投稿2020/04/09 04:12

yominet

総合スコア187

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

u.sayaka0112

2020/04/09 07:00

回答ありがとうございます! python だと print('hoge' + \n)とかでしょうか。
hayataka2049

2020/04/09 08:20

デフォルトで改行されるのでprint('hoge' + \n)では二回改行されますね。 python3のprint関数にはend引数(デフォルト"\n")とflush引数(デフォルトFalse)があるので、まあPythonでもその違いはプログラマーが割と簡単に選択できます。 https://docs.python.org/ja/3/library/functions.html#print
guest

0

python だと print('hoge')で終わるので疲れちゃいます!

coutが気に入らないのであればC言語のprintf()も使えます。

「"hoge"」 と 「'hoge'」

"文字列リテラル'文字リテラルで用途が異なります。

int N; intA[210]; は main()の中に書いても良いですよね!!

これがお作法なのか教えて欲しいです。

作法ではありません。
ローカル変数は宣言だけでは0初期化されず、グローバル変数は0初期化されるという違いはあります。

セミコロンを忘れた際に自動で着けてくれないんですか??

セミコロンが補完されて意図していないコードとしてビルドが通ってしまうとこまりますね。

for文等の{}のお作法

個人的に書くコードなら好みで選べばよいです。
settings.jsonに下記リンクの設定を行えば自動整形時に{を行末にできます。
Visual Studio Codeでの行頭カッコを何とかしたい

投稿2020/04/08 16:49

編集2020/04/08 16:50
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問