第四章 数组和指针
code:
// 第四章 数组和指针 // 1、数组 --------------------------------------------------------- #include <iostream> using namespace std; int main() { // both buf_size and max_files are const const unsigned buf_size = 512, max_files = 20; int staff_size = 27; // nonconst // const unsigned sz = get_size(); // const value not known until run time char input_buffer[buf_size]; // ok: const variable string fileTable[max_files + 1]; // ok: constant expression // double salaries[staff_size]; // error: non const variable // int test_scores[get_size()]; // error: non const expression // int vals[sz]; // error: size not known until run time return 0; } #include <iostream> using namespace std; int main() { const unsigned array_size = 5; // Equivalent to ia = {0, 1, 2, 0, 0} // ia[3] and ia[4] default initialized to 0 int ia[array_size] = { 0, 1, 2 }; //啊哈磊没有说错,ar[..]={0},就可以全部初始化 // Equivalent to str_arr = {"hi", "bye", "", "", ""} // str_arr[2] through str_arr[4] default initialized to the empty string string str_arr[array_size] = { "hi", "bye" }; return 0; } //CppPrimer.cpp:7: error: ISO C++ forbids assignment of arrays #include <iostream> using namespace std; int main() { int a[]={1,2}; int b[2]; b=a; return 0; } #include <iostream> using namespace std; int main() { const size_t array_size = 10; int ia[array_size]; // 10 ints, elements are uninitialized // loop through array, assigning value of its index to each element for(size_t ix = 0; ix != array_size; ++ix) ia[ix] = ix; return 0; } #include <iostream> using namespace std; int main() { const size_t array_size = 7; int ia1[] = { 0, 1, 2, 3, 4, 5, 6 }; int ia2[array_size]; // local array, elements uninitialized // copy elements from ia1 into ia2 for(size_t ix = 0; ix != array_size; ++ix) ia2[ix] = ia1[ix]; return 0; } // 2、指针的引入 ------------------------------------------------------------ #include <iostream> using namespace std; int main() { int ival = 1024; int *pi = 0; // pi initialized to address no object int *pi2 = &ival; // pi2 initialized to address of ival int *pi3; // ok, but dangerous, pi3 is uninitialized pi = pi2; // pi and pi2 address the same object, e.g. ival pi2 = 0; // pi2 now addresses no object return 0; } #include <iostream> using namespace std; int main() { int ival; int zero = 0; const int c_ival = 0; // int *pi = ival; // error: pi initialized from int value of ival // pi = zero; // error: pi assigned int value of zero int *p; p = c_ival; // ok: c_ival is a const with compile-time value of 0 p = 0; // ok: directly initialize to literal constant 0 return 0; } #include <iostream> using namespace std; int main() { double dval; double *pd = &dval; // ok: initializer is address of a double double *pd2 = pd; // ok: initializer is a pointer to double // int *pi = pd; // error: types of pi and pd differ // pi = &dval; // error: attempt to assign address of a double to int * return 0; } #include <iostream> using namespace std; int main() { double obj = 3.14; double *pd = &obj; // ok: void* can hold the address value of any data pointer type void *pv = &obj; // obj can be an object of any type pv = pd; // pd can be a pointer to any type return 0; } #include <iostream> using namespace std; int main() { string s("hello world"); string *sp = &s; // sp holds the address of s cout << *sp; // prints hello world return 0; } #include <iostream> using namespace std; int main() { int ival = 1024, ival2 = 2048; int *pi = &ival, *pi2 = &ival2; pi = pi2; // pi now points to ival2 int &ri = ival, &ri2 = ival2; ri = ri2; // assigns ival2 to ival return 0; } // 定义指针的时候,要用n个*,解引用时,只能用一个* #include <iostream> using namespace std; int main() { int ival = 1024; int *pi = &ival; // pi points to an int int **ppi = π // ppi points to a pointer to int int ***pppi = &ppi; cout << *pppi << ' ' << ppi << endl; cout << *ppi << ' ' << pi << endl; cout << pi << ' ' << *pi << endl; return 0; } // 使用指针访问数组元素 #include <iostream> using namespace std; int main() { int ia[] = {0,2,4,6,8}; int *ip = ia; // ip points to ia[0] int *jp = &ia[0]; cout << ip << ' ' << jp << endl; // same cout << ia[2] << ' ' << *(jp+2) << endl; // same return 0; } #include <iostream> using namespace std; int main() { int ia[] = {0,2,4,6,8}; int *ip = ia; // ip points to ia[0] int *jp = &ia[3]; ptrdiff_t n; // ok: distance between the pointers n=ip-jp; cout << n << endl; return 0; } // 负值下标终于出现 #include <iostream> using namespace std; int main() { int ia[] = { 7, 2, 4, 6, 8 }; int i = ia[0]; // ia points to the first element in ia int *p = &ia[2]; // ok: p points to the element indexed by 2 int j = p[1]; // ok: p[1] equivalent to *(p + 1), // p[1] is the same element as ia[3] int k = p[-2]; // ok: p[-2] is the same element as ia[0] cout << i << ' ' << k << endl; return 0; } // 编译运行都木问题,但。。。 #include <iostream> using namespace std; int main() { const size_t arr_size = 5; int arr[arr_size] = {1, 2, 3, 4, 5}; int *p = arr; // ok: p points to arr[0] int *p2 = p + arr_size; // ok: p2 points one past the end of arr // use caution -- do not dereference! cout << *p2 << endl; // !!! return 0; } #include <iostream> using namespace std; int main() { const size_t arr_sz = 5; int int_arr[arr_sz] = { 0, 1, 2, 3, 4 }; // pbegin points to first element, pend points just after the last for(int *pbegin = int_arr, *pend = int_arr + arr_sz; pbegin != pend; ++pbegin) cout << *pbegin << ' '; // print the current element return 0; } // 指向 const 对象的指针 #include <iostream> using namespace std; int main() { const double d=3.14; const double *cptr; // cptr may point to a double that is const cptr=&d; // ok // *cptr = 4.14; // error: d is const double *pt; // pt=&d; // error: because C++ 语言强制要求指向 const 对象的指针也必须具有 const 特性 double e=5.14; pt=&e; // ok, of course cptr=pt; // ok:cptr本身不是常数 cout << *cptr << endl; // *cptr = 6.14; // error: 虽然可以改变cptr,但*cptr不能作为左值 // cptr 自以为指向 const 的指针 return 0; } // const 指针 #include <iostream> using namespace std; int main() { int errNumb = 0, i=1; int *const curErr = &errNumb; // curErr is a constant pointer //从右向左把上述定义语句读作“curErr 是指向 int 型对象的 const 指针”。 // curErr = &i; //不可以,因为 const 指针 不可以改变 errNumb = 2; // 可以,指针指向对象非 const return 0; } #include <iostream> using namespace std; int main() { const double pi = 3.14159; // pi_ptr is const and points to a const object const double *const pi_ptr = π // 可从右向左阅读上述声明语句:“pi_ptr 首先是一个 const 指针, // 指向 double 类型的 const 对象”。 return 0; } #include <iostream> using namespace std; int main() { string const s1; // s1 and s2 have same type, const string s2; // they're both strings that are const return 0; } // 3、C 风格字符串 ----------------------------------------------------------- #include <iostream> using namespace std; int main() { char ca1[] = {'C', '+', '+'}; // no null, not C-style string char ca2[] = {'C', '+', '+', '\0'}; // explicit null char ca3[] = "C++"; // null terminator added automatically const char *cp = "C++"; // null terminator added automatically char *cp1 = ca1; // points to first element of a array, but not C-style string char *cp2 = ca2; // points to first element of a null-terminated char array return 0; } #include <iostream> #include <cstdio> using namespace std; int main() { const char *cp = "some value"; while(*cp) { printf("%c",*cp); ++cp; } return 0; } /* 对大部分的应用而言,使用标准库类型 string,除了增强安全性外,效率也提高了,因此应该尽量避免使用 C 风格字符串。 作者讲解这部分,主要是为了与以前的C语言编写的代码兼容。。 故以下略去一部分。 */ #include <iostream> #include <string> using namespace std; int main() { int *pia = new int[10]; // array of 10 uninitialized ints string *psa = new string[10]; // array of 10 empty strings int *pib = new int[10]; // array of 10 uninitialized ints int *pic = new int[10](); // array of 10 initialized ints return 0; } // const 对象的动态数组 #include <iostream> #include <string> using namespace std; int main() { // error: uninitialized const array // const int *pci_bad = new const int[100]; // 因为int是内置类型 // ok: value-initialized const array const int *pci_ok = new const int[100](); // ok: array of 100 empty strings const string *pcs = new const string[100]; // 因为string是类类型 return 0; } // 使用数组初始化 vector 对象 #include <iostream> #include <string> #include <vector> using namespace std; int main() { const size_t arr_size = 6; int int_arr[arr_size] = { 0, 1, 2, 3, 4, 5 }; // ivec has 6 elements: each a copy of the corresponding element in int_arr vector < int > ivec(int_arr, int_arr + arr_size); return 0; } // 4、多维数组 -------------------------------------------------------------- #include <iostream> #include <string> #include <vector> using namespace std; int main() { int ia[3][4] = { /* 3 elements, each element is an array of size 4 */ { 0, 1, 2, 3 }, /* initializers for row indexed by 0 */ { 4, 5, 6, 7 }, /* initializers for row indexed by 1 */ { 8, 9, 10, 11 } /* initializers for row indexed by 2 */ }; // equivalent initialization without the optional nested braces for each row int ib[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; int ic[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; int id[300][400] = {0}; //这样清零比较爽 return 0; } #include <iostream> #include <string> #include <vector> using namespace std; int main() { const size_t rowSize = 3; const size_t colSize = 4; int ia[rowSize][colSize]; // 12 uninitialized elements // for each row for(size_t i = 0; i != rowSize; ++i) // for each column within the row for(size_t j = 0; j != colSize; ++j) // initialize to its positional index ia[i][j] = i * colSize + j; return 0; } #include <iostream> #include <string> #include <vector> using namespace std; int main() { int row=3, col=4; int ia[row][col]; for( int i=0; i!=row; ++i ) for( int j=0; j!=col; ++j ) ia[i][j] = i*col+j; // for( int i=0; i!=row; ++i ) { for( int j=0; j!=col; ++j ) cout << ia[i][j] << " "; cout << endl; } return 0; } // 两维数组的指针 #include <iostream> #include <string> #include <vector> using namespace std; int main() { int row=3, col=4; int ia[3][4]; for( int i=0; i!=row; ++i ) for( int j=0; j!=col; ++j ) { ia[i][j] = i*col+j; cout << i << ' ' << j << ' ' << &ia[i][j] << endl; } // 确实是连续存放的 int *pa=&ia[0][0]; //pa的类型是整数 int *pb=&ia[1][0]; cout << pa << ' ' << pb << endl; ptrdiff_t n=pb-pa; cout << n << endl; // 两行第一个位置之间,差4个位置 // int (*ipa)[4]=ia; // ipa的类型是4个整数!这才是一行的指针 int (*ipb)[4]=ia; // 这就是定义4个int作为一个数据类型的方法 ipa = &ia[0]; ipb = &ia[1]; cout << endl << ipa << ' ' << ipb << endl; // pa和ipa的值相同,但意义是不同的,请看: cout << pa+1 << endl; // +1 cout << ipa+1 << endl; // +4 return 0; } // typedef... #include <iostream> #include <string> #include <vector> using namespace std; int main() { int row=3, col=4; int ia[3][4]; for( int i=0; i!=row; ++i ) for( int j=0; j!=col; ++j ) { ia[i][j] = i*col+j; cout << i << ' ' << j << ' ' << &ia[i][j] << endl; } typedef int int_array[4]; //定义4个int作为一个数据类型 int_array *ipa = ia; // cout << endl << ipa << ' ' << ipa+1 << ' ' << ipa+2 << endl; cout << *ipa << ' ' << *ipa+1 << endl; for( int_array *p=ia; p!=ia+3; ++p) for( int *q=*p; q!=*p+4; ++q) cout << *q << endl; return 0; }