C++ Primer 總結之Chap4 Arrays and Pointers
本系列為本人溫習C++基礎時所記的tips,歡迎各位同學指正,共同進步TvT。
Modern C++ programs should almost always use vector and iterator in preference to the lower-lever array and pointer.
int ia[5] = {1, 1, 1}; // {1, 1, 1, 0, 0}
char ch1[] = {'d'}; // no null character('\0')
char ch2[] = "d"; // null terminator added automatically
cout << ch1 << endl; // error happens
char ch3[3] = "aaa"; // wrong, size should be >= 4
A non-const variable or a const variable whose value is not known until run time, cannot be used to specify the dimension of an array.
For built-in type, variables defined outside the body of a function, or say, global variables, are initialized to zero. Local variables are uninitialized. For class type
Drawbacks of array:不能整體拷貝或複製,不能整體作為引數傳入函式,要麼退化為指標,要麼退化為引用;不能作為函式的返回型別;不知道自己的大小,無法動態改變大小,插入更多值的方法只能是重建一個更大的陣列再把值一個個複製過去。
The right type to use for the index/size in array is size_t
Pointer
int a = 5;
int *pt = &a; // pointer to a
int **ppt = &pt; // pointer to the pointer pt
cout<<pt<<endl; // address of a, content of pt
cout<<ppt<<endl; // address of pt, content of ppt
cout<<*ppt<<endl; // address of a
cout<<**ppt<<endl; // 5
int *p0 = 0, *p1 = 0; // 0x00000000
int zero = 0;
int *p2 = zero;// wrong! Must known at compile time
void *p3 = &zero; // Any pointer to data can be implicitly
// converted to void*
cout << *(int*)p3; // 0
const int con = 4;
const int *p4 = &con; // pointer to const like const_iterator
int *p5 = &con; // error
int *const p6 = &zero; // const pointer, can't point to
// objects other than the one initialized,
// actually lose the meaning of pointer
const int *const p7 = &con; // const pointer to const object
typedef string *pstring; // typedef is not simply repalcement,
// it has syntax meaning
// const pstring != const string*
// All of them are const pointers to string
// const pstring == pstring const == string *const
char ch1[] = {'K','T'};
cout << ch1;
//output: KT燙燙燙L?
char *ch2 = "ldfkj";
*ch2 = 'u'; // wrong!!! "ldfkj" is const char*, although it is
// allowed to initialize ch2 for historic reason,
// we should never change the content of it!!!
char *ch3 = ch1;
while(*ch3){
//do somthing
++ch3;
}// Fail if the string is not null-terminated.
// What's worse, it will not crash but end output until
// it meets a null pointer somewhere
A pointer holds the address of another object.
&:address-of operator
Uninitialized pointers are a common source of run-time errors. And we have no way to know if a pointer is valid.
void*
pointer is a special pointer type that can hold an address of any object. And in most cases, the pointer to a function can also be cast tovoid*
. We can dereference it after it be cast to a specific pointer with real typeWhen we use the name of an array in an expression, that name is automatically converted into pointer to the first elment of the array.
When a pointer plus or subtract an integer, the value changed is related to the type of the pointer
ptrdiff_t is a machine-specific signed integral type used to put the difference between pointers.
We can use the subscript operator on any pointer, as long as that pointer points to an elment in an array. Also, the subscripts can be negative.
It is legal to compute an address one past the end of an array or object.
There is no way for the pointer to const to know if the object it points to is actually a const or not. So it treats all objects to which it might point as const.
Think of pointers to const as “pointers that think they point to const”
type *var;
is plain pointer,type *const var;
is const pointer.The type of a string literal is an array of const
char
, it can be implicitly transformed to constchar*
(actuallychar*
is also allowed).The behavior of modifying the content of pointer which points to the address one past the end of an array is undefined.
malloc/free
vsnew/delete
; When we dynamically allocate an array, we specify the type and size but not a name of the array. Instead we return a pointer pointing to the head of the array. We can not use subscript in this case.
int *p_arr = new int[12];// built-in, not initialized
// class, default constructor
const int *p1 = new const int[10]; //error, uninitialized const array
const int *p2 = new const int[10](); //ok, value-initialized
int *p3 = new int[0]; // points to no element
delete [] p_arr; // 不可偏移
string str;
const char *p = str.c_str();
int arr[3] = {0, 1, 3};
vector<int> ivec(arr, arr+3);//Use array to init
//delete後可以賦值
int b = 5;
int *p1 = new int[3]();
int *p2 = &b;
delete [] p1;
p1 = p2;
// explicitly initialize only element 0 in each row
int ia[3][4] = { {1}, {}, {3} };
int (*pia)[4] = ia; // pointer to 2-D array
pia = &ia[1]; // refer to the second row
cout << pia << *pia; // means address of the second row
// and address of first element of the second row, respectively
// same in value
cout << **pia; // 0
// parentheses are important
int *ip[4]; // array of pointers
int (*ip)[4]; // pointer to array
int temp[2][3] = { {1,2,3}, {4,5,6} };
int (*p)[3] = temp;
++p; // point to the second element of temp,
// which is an array of 3 elements, so
// *p is still still still a 【pointer】 pointing to the
// first element of the second array of temp
cout << **p; // 4, not 2
typedef int int_arr[3];
int_arr *ip = temp;
for(int_arr *p = temp;p != temp + 2;++p)
for(int *q = *p;q != (*p) + 3;++q)
cout << *q << endl;
只要有new就要記得delete
string 中沒有返回
char*
的函式,只有返回const char*
的。char*
在輸出的時候,<<
針對它過載過,直接輸出其指向的字串而非地址;若需要輸出地址,先轉為void*
,或使用printf("%p",ptr)
Reference : C++ Primer 4th edition(評註版)