◎基本概念
Data type
call by value、call by pointer、Call by reference
◎簡單實例
pointer to char
step 1. vas 配置 pointer in memory。
step 2. "Hello" 為 const char array in memory,且不可變(constant)。
step 3. pointer 指向 starting address of this const char array in memory。
step 4. = "新字串",會更動pointer指向新字串。
vas 是 pointer to "不可變"的 const char array "Hello" 的 start address。
雖然可以成功編譯,但是其實是不怎麼好的寫法, 因為將const char array 轉成 非-常數(non-const)的char 指標, 雖然很多compiler為了確保向下兼容(backward compatibility), 而支援這種寫法。
若替代 const array of char "Hello",為 非const 的char array
以下宣告方式錯誤,因為 *vad[] 為an array of pointer to char ,"Hello"字串明顯不是 an array of pointer to char,理所當然放不進,而放入 pointer to char進array的方法有,
char *vad[] = { "Hello" },為an array of one pointer to the char。
an array of pointer to char
若替代 array內pointer to char內的指向的const array of char,為 非const 的char array
6個陣列元素包含 hello 5個字元 和 '\0'
Data type
call by value、call by pointer、Call by reference
◎簡單實例
pointer to char
step 1. vas 配置 pointer in memory。
step 2. "Hello" 為 const char array in memory,且不可變(constant)。
step 3. pointer 指向 starting address of this const char array in memory。
step 4. = "新字串",會更動pointer指向新字串。
vas 是 pointer to "不可變"的 const char array "Hello" 的 start address。
雖然可以成功編譯,但是其實是不怎麼好的寫法, 因為將const char array 轉成 非-常數(non-const)的char 指標, 雖然很多compiler為了確保向下兼容(backward compatibility), 而支援這種寫法。
char *vas = "Hello"; //OK //vas[i] 相等於 *(vas + i) cout << typeid(vas).name() << endl;//char * cout << typeid((*vas)).name() << endl;//char cout << typeid(vas[0]).name() << endl;//char //pointer 4 bytes 、char 1bytes cout << sizeof(vas) << endl;//4 cout << sizeof((*vas)) << endl;//1 cout << sizeof(vas[0]) << endl;//1 //雖然型態是指標,(vas + i ) 值是從指向位址開始的整個 character sequence not its address. cout << vas << endl;//Hello cout << vas + 1 << endl;//ello cout << vas + 2 << endl;//llo cout << vas + 3 << endl;//lo cout << vas + 4 << endl;//o //型態是char,讀取指標指向的its address character value , not 指向位址開始的整個 character sequence. cout << *vas << endl;//H cout << *(vas + 1) << endl;//e cout << *(vas + 2) << endl;//l cout << *(vas + 3) << endl;//l cout << *(vas + 4) << endl;//o //vas[i] 相等於 *(vas + i) cout << vas[0] << endl;//H cout << vas[1] << endl;//e cout << vas[2] << endl;//l cout << vas[3] << endl;//l cout << vas[4] << endl;//o vas = "world";//OK,更動pointer,而非 "不可變"的 const char array "Hello" //*vas = 'a';//擲回例外狀況: 寫入存取違規。因為企圖更動 "不可變"的 const char array "Hello"
若替代 const array of char "Hello",為 非const 的char array
- 可以對指向的array of char內的字元進行更動。
- 允許重新指向array of char,且允許重新指向array of char內char數不同。
- 允許const array of char與array of char之間互相重新指向。
- 若重新指向const array of char,array of char隱性轉成const,不可以對const array of char中的char進行更動。
- 若重新指向array of char,可以對array of char中的char進行更動。
char temp[] = { 'h','e','l','l','o','\0' }; char temp2[] = { 'w','o','r','l','d','\0' }; char temp3[] = { 's','w','o','r','l','d','\0' }; char *vas = temp; //OK //vas[i] 相等於 *(vas + i) cout << typeid(vas).name() << endl;//char * cout << typeid((*vas)).name() << endl;//char cout << typeid(vas[0]).name() << endl;//char //pointer 4 bytes 、char 1bytes cout << sizeof(vas) << endl;//4 cout << sizeof((*vas)) << endl;//1 cout << sizeof(vas[0]) << endl;//1 //雖然型態是指標,(vas + i ) 值是從指向位址開始的整個 character sequence not its address. cout << vas << endl;//Hello cout << vas + 1 << endl;//ello cout << vas + 2 << endl;//llo cout << vas + 3 << endl;//lo cout << vas + 4 << endl;//o //型態是char,讀取指標指向的its address character value , not 指向位址開始的整個 character sequence. cout << *vas << endl;//H cout << *(vas + 1) << endl;//e cout << *(vas + 2) << endl;//l cout << *(vas + 3) << endl;//l cout << *(vas + 4) << endl;//o //vas[i] 相等於 *(vas + i) cout << vas[0] << endl;//H cout << vas[1] << endl;//e cout << vas[2] << endl;//l cout << vas[3] << endl;//l cout << vas[4] << endl;//o *vas = 'a';//OK,非const cout << vas << endl;//aello vas = temp2;//OK,更動pointer cout << vas << endl;//world vas = temp3;//OK,更動pointer,允許array內char數不同 cout << vas << endl;//sworld vas = "another";//OK,更動pointer,but 指向的array隱性轉換成const cout << vas << endl;//another //*vas = 'x';//擲回例外狀況: 寫入存取違規。因為企圖更動 "不可變"的 const char array "Hello" vas = temp3;//OK,更動pointer,but 指向的const array隱性轉換成非const *vas = 'x';//OK cout << vas << endl;//xworld
以下宣告方式錯誤,因為 *vad[] 為an array of pointer to char ,"Hello"字串明顯不是 an array of pointer to char,理所當然放不進,而放入 pointer to char進array的方法有,
char *vad[] = { "Hello" },為an array of one pointer to the char。
char *vad[] = "Hello"; //ERROR
an array of pointer to char
char *vad[] = { "Hello","World" };//OK cout << typeid(vad).name() << endl;//char * [2] cout << typeid(*vad).name() << endl;//char* cout << typeid(vad[0]).name() << endl;//char* cout << typeid(*(vad[0])).name() << endl;//char //2 pointer 8 bytes 、pointer 4 bytes 、char 1bytes cout << sizeof(vad) << endl;//8 cout << sizeof((*vad)) << endl;//4 cout << sizeof(vad[0]) << endl;//4 cout << sizeof(*(vad[0])) << endl;//1 //型態為an array of pointer to char,cout出的為陣列儲存位址 cout << vad << endl;//008FF734 //相等於vad[i],型態是指標,值是從指向位址開始的整個 character sequence not its address. cout << *vad << endl;//Hello cout << *(vad + 1) << endl;//World //vas[i],型態是指標,值是從指向位址開始的整個 character sequence not its address cout << vad[0] << endl;//Hello cout << vad[1] << endl;//World //型態是char,讀取指標指向的its address character value , not 指向位址開始的整個 character sequence. cout << *(vad[0]) << endl;//H cout << *(vad[1]) << endl;//W vad[0] = "New String";//OK,更動pointer,而非 "不可變"的 char array or string literal "Hello" //*(vad[0]) = 'k';//擲回例外狀況: 寫入存取違規。因為企圖更動 "不可變"的 const char array
若替代 array內pointer to char內的指向的const array of char,為 非const 的char array
- 可以對array內pointer to char指向的array of char內的字元進行更動。
- 允許array內pointer to char重新指向array of char,且允許重新指向array of char內char數不同 。
- 允許const array of char與array of char之間互相重新指向 。
- 若重新指向const array of char,array of char隱性轉成const,不可以對const array of char中的char進行更動。
- 若重新指向array of char,可以對array of char中的char進行更動。
char temp[] = { 'h','e','l','l','o','\0' }; char temp2[] = { 'w','o','r','l','d','\0' }; char temp3[] = { 's','w','o','r','l','d','\0' }; char *vad[] = { temp,temp2 };//OK cout << typeid(vad).name() << endl;//char * [2] cout << typeid(*vad).name() << endl;//char* cout << typeid(vad[0]).name() << endl;//char* cout << typeid(*(vad[0])).name() << endl;//char //2 pointer 8 bytes 、pointer 4 bytes 、char 1bytes cout << sizeof(vad) << endl;//8 cout << sizeof((*vad)) << endl;//4 cout << sizeof(vad[0]) << endl;//4 cout << sizeof(*(vad[0])) << endl;//1 //型態為an array of pointer to char,cout出的為陣列儲存位址 cout << vad << endl;//008FF734 //相等於vad[i],型態是指標,值是從指向位址開始的整個 character sequence not its address. cout << *vad << endl;//hello cout << *(vad + 1) << endl;//world //vas[i],型態是指標,值是從指向位址開始的整個 character sequence not its address cout << vad[0] << endl;//hello cout << vad[1] << endl;//world //型態是char,讀取指標指向的its address character value , not 指向位址開始的整個 character sequence. cout << *(vad[0]) << endl;//h cout << *(vad[1]) << endl;//w *(vad[0]) = 'k';//OK,非const cout << vad[0] << endl;//kello vad[0] = "New String";//OK,更動pointer,but 隱性轉換成const cout << vad[0] << endl;//New String //*(vad[0]) = 'k';//擲回例外狀況: 寫入存取違規。因為企圖更動 "不可變"的 const char array vad[0] = temp3;//OK,更動pointer,but 指向的const array隱性轉換成非const *(vad[0]) = 'k';//OK cout << vad[0] << endl;//kworldpointer to array of char
6個陣列元素包含 hello 5個字元 和 '\0'
- 若採用char (*x)[6] = &"Hello" 的宣告方式,會出錯,因為"Hello"為const arrays of char,必須宣告為char const (*x)[6] 。
- 不允許對array內的char進行更動,因為array of char宣告為const 。
- 可對指向的陣列位址進行重新指向
- 不允許重新指向的array內char數不同
- 不允許對 (*x) assign array,因為arrays are not assignable.
//pointer to array of char //6個陣列元素包含 hello 5個字元 和 '\0' //char (*x)[6] = &"Hello"; //error, "Hello" are const arrays of char char const (*x)[6] = &"Hello"; cout << typeid(x).name() << endl;//char const (*)[6] cout << typeid(*x).name() << endl;//char const [6] cout << typeid(**x).name() << endl;//char cout << typeid(x[0]).name() << endl;//char const [6] cout << typeid(*x[0]).name() << endl;//char //型態為指標,指向 char const [6] cout << x << endl;//00366B30 //型態為char const [6] cout << *x << endl;//Hello //相等於(*x)[i],型態為char cout << **x << endl;//H //相等於*(x + i),型態為char const [6] cout << x[0] << endl;//Hello //相等於**(x + i),型態為char cout << *x[0] << endl;//H //*x = "world";//error,arrays are not assignable. //**x = 's';//error,為const //x[0] = "world"//error,arrays are not assignable //*x[0] = 'h';//error,為const char temp[] = { 'w','o','r','l','d','\0' }; x = &temp;//OK cout << x << endl;//00AFFCC0 cout << *x << endl;//world //x = &"NewString";//error,const char (*)[10] can't assign to const char (*)[6] x = &"hello";//OK cout << x << endl;//00F06B38 cout << *x << endl;//hello //x = &"helo";//error,const char (*)[5] can't assign to const char (*)[6] char temp2[] = { 'l','w','o','r','l','d','\0' }; //x = &temp2;//error,const char (*)[7] can't assign to const char (*)[6]若要宣告非const的char (*x)[6],可以利用非const 的array of char位址。
- 不可再重新指向const 的array of char 。
- 可以對array內的char進行更動。
- 不允許對 (*x) assign array,因為arrays are not assignable。
char temp[] = { 'h','e','l','l','o','\0'}; char temp2[] = { 'w','o','r','l','d','\0' }; char (*x)[6] = &temp; cout << typeid(x).name() << endl;//char (*)[6] cout << typeid(*x).name() << endl;//char [6] cout << typeid(**x).name() << endl;//char cout << typeid(x[0]).name() << endl;//char [6] cout << typeid(*x[0]).name() << endl;//char //型態為指標,指向 char const [6] cout << x << endl;//00AFF714 //型態為char const [6] cout << *x << endl;//hello //相等於(*x)[i],型態為char cout << **x << endl;//h //相等於*(x + i),型態為char const [6] cout << x[0] << endl;//hello //相等於**(x + i),型態為char cout << *x[0] << endl;//h //x = &"hello";//error,const char (*)[6] can't assign to char (*)[6],沒有隱性轉換const問題 x = &temp2;//OK cout << x << endl;//00AFF704 cout << *x << endl;//world //*x = temp2 //error,arrays are not assignable. //*x = "world";//error,arrays are not assignable. **x = 's';//OK,不為const cout << x << endl;//00AFF704,沒變 cout << *x << endl;//sorld //x[0] = "world"//error,arrays are not assignable. *x[0] = 'x';//OK,不為const cout << x << endl;//00AFF704,沒變 cout << *x << endl;//xorld
留言
張貼留言