1
2

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 3 years have passed since last update.

[C++] 注意点 まとめ (初心者)

Last updated at Posted at 2020-03-12

#c++の注意点をまとめておく

学んでいる中で、気を付けなければいけないと思った点をまとめておく。

##cin.get()の振る舞い

int a = cin.get();
cout << a << endl;

で、4を入力すると

52

と出力された。おそらく、ASCII文字として入力されているはず。一方、

int a;
cin >> a;
cout << a << endl;

で、4を入力すると、

4

と出力される。

あと、これはシステム依存らしいが、EOFと入力しても初めのEしか読み込まず、

69

と出力される。get()メソッドがchar型でunsigned int型で読み込んでいるのか、EOFを一文字と認識していないのでEOFのASCIIコードの-1が出力されない。

他にも、unsigned int型に収まるEOTCANなども頭文字のECに対するASCIIコードが出力されてしまう。

当然、-1を入力しても-に対するASCIIコードが出力される。

また、ANSI規格によるとEOFは負の整数値となっていて必ずしも-1であるとは限らないらしい。(1998年出版の本C++プログラミング〈Vol.1〉 (Computer Science Textbook)より)

###※追記

Windows 10環境では<ctrl>zEOF-1が出力されました。

なお、<crtl>dだとEOT4が出力されました。

##switch構文

switch構文は、ほかの制御構造と違い、case節の中に複数のアクションを書いても、それらを{}でくくる必要はない。

また、switch構造の複数の条件に対して同じ命令をしたい場合は次のように表記できる。

int input = cin.get();

switch (input) {
    case 'A': case 'a':
        cout << "Input is A or a." << endl;
        break;
}

##引数を取らない関数の[C]と[C++]の違い

C++で引数を取らない関数の宣言は二通りある。

void f1();
void f2(void);

しかし、C++における空の関数パラメータリストの意味はCの場合とは全く異なる。

  • 空の関数パラメータの意味
    • Cの場合
      • 引数チェックが何も行われないことを意味する(つまり、関数呼び出しのときにどんな引数でも渡すことができる)
    • C++の場合
      • その関数が引数を取らないことを意味する(つまり、引数を渡すとコンパイルエラーになる)

##:: scope resolution operator(単項スコープ特定演算子)

単項スコープ特定演算子::の挙動を確認しておく。


#include <bits/stdc++.h>
using namespace std;

void f(int a);

int n = 10; //global number n initialezed 10

int main() {
   
    f(0);

    cout << "incremented global n in main() = " << n << endl;

    return 0;
}

void f(int a) {
    int n=1; // initialize local number n

    cout << "local n in f() = " << n << endl;

    cout << "scope resolution operator ::n = " << ::n << endl;

    ::n++;

    cout << "incremented scope resolution operator ::n in f() = " << ::n << endl;

    return;
}

結果は次のようになった。

local n in f() = 1
scope resolution operator ::n = 10
incremented scope resolution operator ::n in f() = 11
incremented global n in main() = 11

単項スコープ特定演算子::を使えば、ローカル関数内で同じ変数名を定義してもグローバル変数にアクセスできる。

グローバル変数と同じ名前の変数がなければ直接アクセスできる。

※注意:ただし、ローカル関数f()からmain()内のローカル変数にはアクセスできない!!!

###呼び出し元関数内のローカル変数を直接変更するには関数パラメータの型の後に&(アンパサンド)をつけて参照渡しにする

呼び出し元のローカル変数を直接変更する方法は&を用いて次のようにすればいい。

#include <bits/stdc++.h>
using namespace std;

void f(int &a);

int main() {
    int n = 10;

    cout << "local n = " << n << endl;

    f(n);

    cout << "new n = " << n << endl;
    
    return 0;
}

void f(int &a) {
    a++;

    cout << "incremented a = " << a << endl;

    return;
}

結果は次のようになり、main()内のローカル変数nが更新されているのがわかる。

local n = 10
incremented a = 11
new n = 11

##*pointer(ポインタ)

C++ではNULLポインタは0と等価である。

0は単なる整数値だが、ポインタ型にキャストしなくても直接代入することができる。

C++では0での初期化がよく使われます。

int y = 5;
int *xPtr, *yPtr;

xPtr = 0;
yPtr = &y;

また、*&は対照的な関係になっているので、

#include <bits/stdc++.h>
using namespace std;

int main() {
    int a;
    int *aPtr;

    a = 7;
    aPtr = &a;

    cout << "a = " << a << endl;
    cout << "*aPtr = " << *aPtr << endl;
    cout << endl;
    cout << "&a = " << &a << endl;
    cout << "aPtr = " << aPtr << endl;
    cout << endl;
    cout << "&*aPtr = " << &*aPtr << endl;
    cout << "*&aPtr = " << *&aPtr << endl;
    cout << endl;
    cout << "&aPtr = " << &aPtr << endl;

    return 0;
}
a = 7
*aPtr = 7

&a = 0x61fe1c
aPtr = 0x61fe1c

&*aPtr = 0x61fe1c
*&aPtr = 0x61fe1c

&aPtr = 0x61fe10

###整数への定数ポインタの初期化

整数への定数ポインタはint * const型で定義する。

初期化は整数にアドレスを意味する&をつけて、ポインタとして渡す。

int x;

int * const ptr = &x;

整数への定数ポインタはポインタptrの値は変更できないが、ポインタ先の整数*ptrは変更可能。

###整数型定数への定数ポインタの初期化

整数型定数への定数ポインタはconst int * const型で定義する。

初期化は定数変数に&をつけてアドレス(ポインタ)で渡す。

int x = 5;

const int * const ptr = &x;

整数型定数への定数ポインタはポインタptrもポインタ先の整数*ptrも変更できない。

1
2
7

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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?