c言語ポインタ初探一ポインタと参照(二)


前に引用に言及しましたが、ここではさらに深く研究します.
参照
リファレンスはある(オブジェクト)の別名であり、リファレンスに対する操作は変数に対する直接操作と全く同じであり、リファレンスは別のポインタと見なすことができる.
int x=10;
int &rx=x;
参照rxをint型変数xの別名として宣言します.参照を宣言するときは注意してください.
(1)宣言されると、変更できません.c++は、宣言が完了した後に参照の値を変更することはできません.
(2)参照を宣言するときは、同時に初期化しなければならない.宣言されると修正できないため、参照の初期化は必須である.初期化されていない参照は無効です.
(3)宣言文のタイプ識別子は、初期値の変数タイプと一致しなければならない(特殊な場合は後述).
二参照の使用制限:
1.配列の参照は作成できません.配列はいくつかの要素からなる集合であり、配列の別名を確立することはできません.
2.参照の参照を宣言できません.
int & & refNum=num;  //  
3.参照へのポインタの宣言
int num=10;
int & *pNum=num; //  

ただし、ポインタの参照は宣言できます.
#include 
using namespace std;
int main()
{
    int num=10;
    int *pNum=&num
    int *&refNum=pNum;
    cout<

三その他
C++プログラムはnewで申請した動的無名エンティティに対して参照を確立することができる.
#include 
using namespace std;
int main()
{
    int &refNum=*new int(10);
    cout<

ダイナミックメモリを取り消す場合はdelete&refNumを使用できます
#include 
using namespace std;
int main()
{
    int &refNum=*new int(10);
    delete &refNum;
    return 0;
}
new出願の動的配列に対する参照を確立することは違法である.
宣言文のタイプ識別子は、初期値の変数タイプと一致する必要がありますが、両者が異なる場合、constで修飾されていない限り、賢いコンパイラがエラーを指摘する場合があります.この場合、c++は一時的な変数を生成し、以下の使用法が適用されます.
#include 
using namespace std;
int main()
{
    const int & refInt=9;   //  const     (        )
    cout<
const修飾の参照は読み取り専用で書き換えられません.
四ポインタとconst
const修飾子で宣言されたプログラムエンティティは読み取り専用であり、ポインタを宣言する場合、宣言文の異なる場所でconstを使用することで効果は異なります.
(1)ポインタへの値付けを禁止する.
(2)間接参照(*ポインタ)によるポインタの指す変数への値付けを禁止する.
(3)すなわち(1)また(2)である.
1.書き換え禁止ポインタ(定数ポインタまたは定数ポインタ)
ポインタを宣言するとき、*の右側にconst修飾子を付けると、宣言されたポインタは定数ポインタ(通常ポインタ)コンパイラと呼ばれ、ポインタの値を書き換えることはできません.つまり、ポインタはメモリアドレスを指します.
#include 
using namespace std;
int main()
{
    int num=10,num2=20;
    int * const pNum=&num
    cout<
プログラムの実行中、pNumの値は変更できません.つまり、他のメモリユニットを指すことはできませんが、変数の値を間接的に変更することができます.
#include 
using namespace std;
int main()
{
    int num=10,num2=20;
    int * const pNum=&num
    cout<

通常ポインタを宣言する場合は、宣言が完了した後に変更できないため、初期化されていない通常ポインタ式は意味がなく、コンパイラがエラーを報告するため、初期化する必要があります.
2.間接参照の上書き禁止
ポインタ宣言時にconst修飾子をポインタタイプの前に置くと、ポインタが指す変数を間接的に参照して書き換えることはできません(ただし、変数は直接変更されます).
#include 
using namespace std;
int main()
{
    int num=5;
    const int *pNum=&num;     //       int const *pNum=&num
    *pNum=10;   //  
    num=10;
    return 0;
}

3.書き換え禁止ポインタと書き換え禁止間接引用
3は上の2種類の「併集」で、それでは文法もそのような併集であるべきである---やはりそうである
#include 
using namespace std;
int main()
{
    int num=5,num2=10;
    const int * const pNum=&num
    *pNum=10;   //  
    pNum=&num2;  //  
    num=10;
    return 0;
}

五constを用いて関数の頑丈性を高める
1.constで関数を修飾するパラメータ
パラメータが出力用であれば、どのデータ型であっても、ポインタ転送を採用しても、参照転送を採用してもconstを追加することはできません.そうしないと、パラメータは出力機能を失います.
constは入力パラメータのみを修飾できます
(1)例えばStringCopy関数:
void StringCopy(char *strDestination,const *strSource)
ここでstrSourceは入力パラメータ、strDestinationは出力パラメータであり、strSourceにconst修飾を加えた後、関数内の文がstrSourceの内容を変更しようとすると、コンパイラはエラーを報告します.
(2)入力パラメータが「値伝達」を使用している場合、関数はこのパラメータをコピーするために一時変数を自動的に生成するので、保護する必要はありません.
(3)内部データ型以外のパラメータについては,void fun(A a)のようにvoid fun(const A&a)と書くべきであり,効率的で安全である.しかし内部データvoid fun(int x)についてはそう書く必要はありません.
2.constで関数の戻り値を修飾する
(1)ポインタ伝達方式の関数の戻り値にconst修飾関数の戻り値を加える(すなわちポインタの内容が変更できない場合、その戻り値はconst修飾を加えた同型ポインタにしか与えられない
#include 
using namespace std;
const int *fun()
{
    int num=3;
    int *pNum=&num
    return pNum;
}
int main()
{
    const int *p=fun();  //  const   
    cout<

(2)関数の戻り値が値伝達方式を採用する場合,const修飾を加える価値はない.
たとえば、関数int Fun()をconst int Fun()と書かないでください.
関数A Fun()をconst A Fun()と書かないでください.
3.constメンバー関数
データ・メンバーを変更しない関数はconstとして宣言する必要があります.const関数を作成するときに、データ・メンバーを不注意で変更したり、他の非constメンバー関数を呼び出したりすると、コンパイラが指摘します.
#include 
using namespace std;
class fun
{
private:
    int num;
public:
    fun(int Num=0):num(Num)
    {}
    void Add(int elem)
    {
        num+=elem;
    }
    int GetCount() const
    {
        num-=1;     //    
        Add(10);     //    
        return num;
    }
};
int main()
{
    fun f;
    f.Add(10);
    cout<