【Cとポインタ】constポインタ

4602 ワード

一、入門
constポインタ
ポインタが指す内容は変えられず、ポインタが指す内容を変えることができる.
constへのポインタ
ポインタは指向を変えることができなくて、ポインタは内容を指すことができます
 
#include "stdio.h" 

int main() 
{ 
   //const    (          ,        ) 
	int a = 5;   
	int b = 6;   
	const int *ptr = &a;   
	*ptr = 8; //error   
	ptr = &b; //ok;   
	
	//  const    (         ,         )
	int a = 5;   
	int b = 6;   
	int * const ptr = &a;   
	*ptr = 8; //ok   
     ptr = &b; //error
} 


 
二、深さ解析
大まかに言えば、const修飾ポインタ、const修飾参照、const修飾ポインタの参照の3つに分けられる.const修飾ポインタconst修飾ポインタ自体const修飾ポインタが指す変数(またはオブジェクト)const修飾ポインタ自体とポインタが指す変数(またはオブジェクト)1)const修飾ポインタ自体の場合、ポインタ自体は定数であり、pは変更できない、ポインタ自体を修正する行為はすべて不法である.
例:
const int a = 1; 
const int b = 2; 
int i = 3; 
int j = 4; 
int* const pi = &i; //ok, pi    int* const , &i    int* const 
int* const pi = &a; //error, pi    int* const, &a    const int* const 
pi = &j; //error,      ,    
*pi = a; //ok, *pi         ,   

このことから,piは定数であり,定数は初期化と付与時にタイプが厳密に一致しなければならない.すなわちconstがポインタ自体を修飾する場合、=番号の両側の変数タイプは厳密に一致しなければならない.そうしないと一致しない.2)const修飾ポインタが指す変数(またはオブジェクト)の場合、間接参照ポインタによって変数の値を変更することはできません.ポインタがpであると仮定すると*pは可変ではありません.次に例を挙げて説明します.
const int *pi = &a; //      int const *pi = &a; 
        const int *pi = &i; //ok ,pi        ,         
         const int *pi1 = &a; 
        const int *pi = pi1; //ok 
        *pi = j; //error,*pi    ,              
         pi = &j; //ok,pi   
         pi = &b; //ok,pi   
         pi++; //ok 
         --pi; //ok 

 
3)const修飾ポインタ自体とポインタが指す変数(またはオブジェクト)にポインタpが設けられている場合、pも*pも可変ではない.例を次に示します.
const int* const pi = &a; //or int const* const pi = &a; 
// const pi    ,  (2)    ,    pi   const,     ,=            ,     int*, &a    const int* const,  int*,       。 
const int* const pi = &i; //ok, &i   int* const,  int*,    。 
const int *pi1 = &j; 
const int *const pi = pi1; //ok,  pi1   int* 
pi = &b; //error, pi    
pi = &j; //error, pi    
*pi = b; //error, *pi    
*pi = j; //error, *pi    
pi++; //error ,pi    
++i; //ok, =      (   )          
a--; //error, a const 

 
このような状況は,以上の2つの状況と関係がある.const int*const pi=&a;const int*(const pi)=&aと見ることができます.(必要を表すだけ)const piを一体と見なし,上記分類(2)と合致する.int*さえ含まれていればよい.
const修飾参照は比較的簡単で、修飾ポインタのように複雑ではありません.参照と参照オブジェクトが一体であるため、参照がconst修飾されるのは1つのタイプだけです.const修飾参照は、参照自体は可変ではないが、参照の変数(またはオブジェクト)は変更できる.例:
const int& ri = a; //or int const & ri = a; ok, ri      ,        
const int& ri = i; //ok,        
ri++; //error, ri   ,    
i++; //ok,=           
ri=b; //error, ri    
i=j; //ok,=           
int & const ri = i; //error,       ,     

 
const修飾ポインタの参照は別名にすぎません.ここでは修飾ポインタと似ています.また、(1)まず例をあげます.const int*pi=&a;             const int *&ri = pi;//or int const *&ri = pi; 参照は参照オブジェクトの別名です.だからこそ、riはpiの別名なので、riのタイプはpiと完全に一致しなければなりません.ここでpiのタイプはint*であり,riのタイプもint*であり,付与は可能である.const int*&ri=&a;正しくない?分析してみればわかる.riタイプがint*,&aのタイプがconst int*constと一致しません.         const int *&ri = &i;//Error、タイプが一致しません.1つはint*、1つはint*const ri=&aです.//ok           ri = &i;//ok            const int *pi1=&a;           const int *pi2=&i;           ri = pi1;//ok           ri = pi2;//ok           *ri = i;//error            *ri = a;//errorはこれと1-(2)の違いに注意する.(2)用例説明:int*const&ri=&i;//ri左の&号を外すとint*const riとなり、riは別名であるため、riのタイプは付与数のタイプと一致し、riのタイプはint*const、&iはint*constとなり、このようにすることができる.           int *const &ri = pi;//Error、タイプが合わない、int*const、int*int*const&ri=&a;//error、タイプが合わない、int*const、const int*const(*ri)++;//ok          i++;//ok          ri = &i;//errorの場合、riは定数であり、変更できない.(3)用例説明:const int*pi=&j;          const int* const &ri = pi;//or int const * const &ri = pi;ok           const int* const &ri = &i;//okriはpiの別名であり、piのタイプはriと一致しなければならない.&を取って、const int*const riを得て、const riを一体と見なして、riのタイプ情報を簡単に得ることができて、前の2-(3)で議論したように、riに与えることができるのはタイプint*を含む限りです.piのタイプはint*、&iのタイプはint*constで、そうすることができます.         const int * const &ri = &a;//ok           ri++; //error          *ri = 6; //error