牛客網C++テーマまとめ(一)
4369 ワード
今日から牛客ネットで練習してコード力を高めるつもりですが、最近何をしているのか分からないので、今からまとめを書きたいと思います.
一、関数ポインタの定義:
C++指向関数のポインタの定義方法は次のとおりです.
戻りタイプ(*ポインタ名)(関数パラメータリスト)例えばvoid(*p)(int)は、戻り値voidパラメータがintタイプの関数を指す
例えば、void(*q)(Base,Base)
戻りタイプがvoidで、パラメータリストには2つのBase(ここではクラス名)クラスのパラメータがあります.
二、演算のいくつかの注意点:
以下のプログラムの出力結果は()です.
1
2
3
4
5
6
例えば、上記の問題では、mが整数変数であるため、2700000000と表示されます.m/2は3.5ですが、整数であるため、
の3.同じ1/2ビット0なので、結果は2800000ではなく2700000だった.
三、メモリ位置合わせの原則:
一、構造体変数のヘッダアドレスは、その最も広い基本タイプのメンバーサイズと整列基数の小さい者によって除去することができる.二、構造体の各メンバーの構造体ヘッダアドレスに対するオフセット量(offset)は、メンバーサイズと整列基数の小さい者の整数倍であり、必要に応じてコンパイラはメンバー間に埋め込みバイト(internal adding)を加える.
三、構造体の総サイズは、構造体の最も広い基本タイプのメンバーサイズと整列基数の小さい者の整数倍であり、必要に応じてコンパイラは最後のメンバーの後に充填バイトを加える.
32ビットシステム環境では、コンパイルオプションは4バイトで整列され、sizeof(A)とsizeof(B)は次のようになります.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
構造体(struct)(または連合体(union))のデータメンバーで、各データメンバーの位置合わせがコンパイルオプションで指定されたデータメンバー自体の長さの中で、最も長いものです.
A:
4(int)+4(shortが足りない4,補2)+4(int)+4(charが足りない4,補3)=16
B:
4(int)+4(charが1,shortが2,補1)+4(int)=12
四、虚関数の応用:
以下のプログラムの出力は
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
最後の出力は12です.なぜなら、ベースクラスのポインタが派生クラスのオブジェクトベースクラスポインタを指して虚メンバー関数を呼び出すと、ベースクラスで定義されたメンバー関数ではなく、本当にオブジェクトを指すメンバー関数が呼び出されます.虚関数でなければ、ベースクラスポインタがどの派生オブジェクトを指しているかにかかわらず、呼び出されたのはベースクラスで定義された関数です.
他にも学んだ新しい知識はありませんが、主に細心の注意を払わないのはつらいです.
一、関数ポインタの定義:
C++指向関数のポインタの定義方法は次のとおりです.
戻りタイプ(*ポインタ名)(関数パラメータリスト)例えばvoid(*p)(int)は、戻り値voidパラメータがintタイプの関数を指す
例えば、void(*q)(Base,Base)
戻りタイプがvoidで、パラメータリストには2つのBase(ここではクラス名)クラスのパラメータがあります.
二、演算のいくつかの注意点:
以下のプログラムの出力結果は()です.
1
2
3
4
5
6
main()
{
int
m=7,n=4;
float
a=38.4,b=6.4,x;
x=m/2+n*a/b+1/2;
printf
(
"%f
"
,x);
}
例えば、上記の問題では、mが整数変数であるため、2700000000と表示されます.m/2は3.5ですが、整数であるため、
の3.同じ1/2ビット0なので、結果は2800000ではなく2700000だった.
三、メモリ位置合わせの原則:
一、構造体変数のヘッダアドレスは、その最も広い基本タイプのメンバーサイズと整列基数の小さい者によって除去することができる.二、構造体の各メンバーの構造体ヘッダアドレスに対するオフセット量(offset)は、メンバーサイズと整列基数の小さい者の整数倍であり、必要に応じてコンパイラはメンバー間に埋め込みバイト(internal adding)を加える.
三、構造体の総サイズは、構造体の最も広い基本タイプのメンバーサイズと整列基数の小さい者の整数倍であり、必要に応じてコンパイラは最後のメンバーの後に充填バイトを加える.
32ビットシステム環境では、コンパイルオプションは4バイトで整列され、sizeof(A)とsizeof(B)は次のようになります.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct
A
{
int
a;
short
b;
int
c;
char
d;
};
struct
B
{
int
a;
short
b;
char
c;
int
d;
}
構造体(struct)(または連合体(union))のデータメンバーで、各データメンバーの位置合わせがコンパイルオプションで指定されたデータメンバー自体の長さの中で、最も長いものです.
A:
4(int)+4(shortが足りない4,補2)+4(int)+4(charが足りない4,補3)=16
B:
4(int)+4(charが1,shortが2,補1)+4(int)=12
四、虚関数の応用:
以下のプログラムの出力は
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class
Base {
public
:
Base(
int
j): i(j) {}
virtual
~Base() {}
void
func1() {
i *= 10;
func2();
}
int
getValue() {
return
i;
}
protected
:
virtual
void
func2() {
i++;
}
protected
:
int
i;
};
class
Child:
public
Base {
public
:
Child(
int
j): Base(j) {}
void
func1() {
i *= 100;
func2();
}
protected
:
void
func2() {
i += 2;
}
};
int
main() {
Base * pb =
new
Child(1);
pb->func1();
cout << pb->getValue() << endl;
delete
pb; }
最後の出力は12です.なぜなら、ベースクラスのポインタが派生クラスのオブジェクトベースクラスポインタを指して虚メンバー関数を呼び出すと、ベースクラスで定義されたメンバー関数ではなく、本当にオブジェクトを指すメンバー関数が呼び出されます.虚関数でなければ、ベースクラスポインタがどの派生オブジェクトを指しているかにかかわらず、呼び出されたのはベースクラスで定義された関数です.
他にも学んだ新しい知識はありませんが、主に細心の注意を払わないのはつらいです.