C++の学習
1. C から C++ へ
1. 引用
引用について話す前に、誰もがよく知っている C 言語について話してから、C から C++ に移行しましょう。これにより、C の知識が強化されるだけでなく、C++ も理解しやすくなります。
例 1、価値交換
aとbの値を交換する
C 言語でスワッピングを実装するには、さまざまな方法があります。
- 別の変数 c を仲介として導入し、最初に a の値を c に代入し (c=a)、次に b の値を a に代入し (a=b)、最後に c の a の値を取得して b に代入します。 (b =c) となり、変換が実現されます。
#include <stdio.h>
int main()
{
int a = 100;
int b = 10;
int c;
printf("a = %d, b = %d\n", a, b);
c=a;
a=b;
b=c;
printf("a = %d, b = %d\n", a, b);
}
結果:
@ubuntu:/mnt/hgfs/ub2/$ gcc swap1.c
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 10
a = 10, b = 100
@ubuntu:/mnt/hgfs/ub2/$
- 加算と合計の値に応じて、2 つの値を交換する前後で変化しないため、3 番目の変数を導入することなく解くことができます。b=a+b、a=ba (a=a+ba と同等、最終的に a は b の値を取得)、b=ba (b=a+bb と同等)
#include <stdio.h>
int main()
{
int a = 100;
int b = 10;
printf("a = %d, b = %d\n", a, b);
b=a+b;
a=b-a;
b=b-a;
printf("a = %d, b = %d\n", a, b);
}
結果:
@ubuntu:/mnt/hgfs/ub2/$ gcc swap2.c
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 10
a = 10, b = 100
@ubuntu:/mnt/hgfs/ub2/$
- 論理記号 XOR (^) を使用して実現します。a^=b、b^=a、a^=b。
#include <stdio.h>
int main()
{
int a = 100;
int b = 10;
printf("a = %d, b = %d\n", a, b);
a^=b;
b^=a;
a^=b;
printf("a = %d, b = %d\n", a, b);
}
結果:
@ubuntu:/mnt/hgfs/ub2/$ gcc swap3.c
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 10
a = 10, b = 100
@ubuntu:/mnt/hgfs/ub2/$
より高級に見せるために、関数にカプセル化されています
例 2. 価値交換の最適化バージョン
#include <stdio.h>
void swap(int *p, int *q)
{
*p ^= *q;
*q ^= *p;
*p ^= *q;
}
int main()
{
int a = 100;
int b = 10;
printf("a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("a = %d, b = %d\n", a, b);
}
結果:
@ubuntu:/mnt/hgfs/ub2/$ gcc swap4.c
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 10
a = 10, b = 100
@ubuntu:/mnt/hgfs/ub2/$
これは特に古典的な関数のカプセル化であり、ポインターが使用されている場合にのみ正しいです。ポインタを使用しない場合は、値を返す必要があります。そうでない場合、swap() は役に立たず、以下に示すように値の交換は実行されません。
#include <stdio.h>
void swap(int p, int q)
{
p ^= q;
q ^= p;
p ^= q;
}
int main()
{
int a = 100;
int b = 10;
printf("a = %d, b = %d\n", a, b);
swap(a, b);
printf("a = %d, b = %d\n", a, b);
}
結果:
@ubuntu:/mnt/hgfs/ub2/$ gcc swap4.c
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 10
a = 100, b = 10
@ubuntu:/mnt/hgfs/ub2/$
swap() 関数の終了後は値が返されないため、a と b は交換されません。面接ではこれをテストします。
例 3. 値交換の C++ バージョン
#include <stdio.h>
int swap(int &a, int &b)
{
a ^= b;
b ^= a;
a ^= b;
}
int main()
{
int a = 100;
int b = 10;
printf("a = %d, b = %d\n", a, b);
swap(a, b);
printf("a = %d, b = %d\n", a, b);
}
前述の C 言語の方法に比べて、この表現はより直観的であり、ポインタやアドレスのフェッチと競合する必要がないアイデアです。
int swap(int &a, int &b) ここで、int &a および int &b は参照です。&はC言語のアドレスではなく参照の意味です。たとえば、int a=100、int &b=a、ここで b は a を指します。値の転送だけでなく、アドレスも一貫しています。
#include <stdio.h>
int main()
{
int a =100;
int &b = a;
printf("a = %d, b = %d\n", a, b);
printf("addr: a = %p, b = %p\n", &a, &b);
}
@ubuntu:/mnt/hgfs/ub2/$ g++ test.cpp
@ubuntu:/mnt/hgfs/ub2/$ ./a.out
a = 100, b = 100
addr: a = 0xbfb02ae8, b = 0xbfb02ae8
@ubuntu:/mnt/hgfs/ub2/$
2. 関数のオーバーロード
例 4. 値と文字列の比較
これは非常に簡単です。2 つの数値の差を直接返して値の大小比較を取得できます。文字列のサイズを比較する場合は、ライブラリ関数 strcmp() を使用できます (ヘッダー ファイル string.h を追加する場合)
。 string 関数を使用する)、誰もがそうなると思います。
#include <stdio.h>
#include <string.h>
int intcmp(int a, int b)
{
return a-b;
}
int scmp(const char *str1, const char *str2)
{
return strcmp(str1, str2);
}
int main()
{
printf("%d\n", intcmp(1, 2));
printf("%d\n", scmp("aaaaaa", "bbbb"));
}
ここで、皆さんの注目を集めたかどうかわからない点があります。数値比較と文字列比較はどちらも比較関数ですが、実装するには異なる関数が必要です。関数を利用することは可能でしょうか?はい、C++ の関数のオーバーロードによってこの問題は解決できます。
#include <stdio.h>
#include <string.h>
int cmp(int a, int b)
{
return a-b;
}
int cmp(const char *str1, const char *str2)
{
return strcmp(str1, str2);
}
int main()
{
printf("%d\n", cmp(1, 2));
printf("%d\n", cmp("aaaaaa", "bbbb"));
}
オーバーロードされた関数は、通常、同様の機能を持つ関数のグループに名前を付けるために使用されます。これにより、関数名の数が減り、名前空間の汚染が回避され、プログラムの可読性にとって非常に役立ちます。
3. ヒープメモリの割り当て(新規/削除)
例 5-1. C 言語でのメモリ割り当て (malloc/free)
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main()
{
int *intp = (int*)malloc(sizeof(int));
*intp = 100;
printf("*intp = %d\n", *intp);
free(intp);
char *p = (char *)malloc(10);
strcpy(p, "hello");
printf("p: %s\n", p);
free(p);
}
例 5-2、C++ でのメモリ割り当て (新規/削除)
#include <stdio.h>
#include <malloc.h>
#include <string.h>
int main()
{
int *intp = new int;//(int*)malloc(sizeof(int));
*intp = 100;
printf("*intp = %d\n", *intp);
delete intp;
char *p = new char[10];
strcpy(p, "hello");
printf("p: %s\n", p);
delete [] p;
}
4. デフォルトパラメータを設定する
例 6. 一般的なデバッガの機能
プログラムの実行場所を確認したい場合、「---------------」という文字列を出力して場所を特定することが多いですが、日付を出力するなどマークを付けたい場合もあります。 、説明、その他の文字列。そこで、一般的に使用される「---------------」をデフォルトとして設定し、その他の場合に個別にマークを付けたいと思います。
#include <stdio.h>
void debug(const char *ptr = "---------------")
{
printf("%s\n", ptr);
}
int main()
{
debug();
debug();
debug("hello");
debug();
debug();
debug();
debug("world");
debug();
}
結果:
@ubuntu:/mnt/hgfs/ub2$ g++ debug.cpp
@ubuntu:/mnt/hgfs/ub2$ ./a.out
---------------
---------------
hello
---------------
---------------
world
---------------
@ubuntu:/mnt/hgfs/ub2$