C++Primer读书笔记----第四章数组与指针(2)

指针操作

对指针指向的数据做操作(需要解引):

      int a = 123 ;  

      int *cur = &a ;

      *cur = 456  // 等价于 a = 456; (对所指向的数据做操作需要做解引在做操作(就是在变量引用时保持*号))

对指针本身操作是指改变指针的指向对象:

      int a = 123 ;  

      int *cur = &a ;

      int b = 123 ;  

      int *curb = &b ;

      a = b ;  // 等价于 a = &b  (对指针本身操作不能带解引符号*)  ab两个指针现在都指向了变量 b ,变量 a 现在没有任何指针指向。

 

指针不能直接指向数组变量,它是通过指向数组中得某个项并前后移动来操作数组;

    int a[count] = {1,2,3,...} ;

    int *cur = a ;  // 该操作是简化操作实则是指针指向了数组的第一项,等同于 int *cur = &a[0]

    也可以明确指定 int *cur = &a[2];

 

    指定了数组的指针可以前后移动:
    int *next = cur +1 ; 
    int *prv = cur -1 ; 
    int *next3 = cur +3 ;  // 当前项向后移动三位的项指针


    数组在数据范围前后一位是溢出位,一旦指针到了任意一个溢出位就不能再做解引用。

    int a[10] = {1,2,3,...} ; 

    int *cur = &a[0] ;

    int *cur1 = cur -1 ; // cur1是溢出位,表示指针已经移出数组

    int *cur2 = cur +10 ; // cur1是溢出位,表示指针已经移出数组

 

    两个数组指针可以相减,值是类型为 ptrdiff_t 的项间距(两个操作数中不能有溢出位)如下:

    int a[] = {1,2,3,...} ;  

    int *cur1 = &a[1] ;

    int *cur2 = &a[5] ;

    ptrdiff_t pd = cur2 - cur1 ;  (也可以交换两个操作数的位置,结果允许为负数)

 

    指针可以在数组有效范围内任意移动,找到相应项后如何操作数组的真实值呢? 只需要解引既可。

    int a[] = {1,2,3,...} ;  

    int *cur = &a[1] ;

    *cur = 1 ; //   等同于 a[1] = 1

  

    数组最重要的是下标操作。数组指针也有下标操作,但是意义和数组下标不一样

    int a[] = {1,2,3,...} ;  

    int *cur = &a[1] ;

    cur[1] = 2 ;  // 等价于 *(cur + 2) = 2 也等价于 a[3] = 2

    int i = cur[-2] ;  // 等价于 int i = *(cur - 2) 也等价于 int i = a[1]

 

    指针是数组的迭代器

 
const count = 10;

int arr[count] = {1,2,3...};

for(int *cot = arr; *end = arr + count; cot != end; ++ cot)
{
    cout <<  *cot  << endl;
}
 

  

    可以用const修饰定义指针。 
    指向常量的指针:
      const int a = 123 ;

      const int *cur =&a ; // const 必须

      需要注意:常量的指针必须是指向常量指针,但指向常量指针可以指向常量也可以指向变量。无论如何都不能对它所指内容做更改,即使它实际指向了变量,但可以更改这个指针的指向
      int c =456 ; 

      cur = &c ; // 更改了指针的指向,现在指向的实际是个变量

      *cur = 789 ; // 不允许,虽然指向的是变量但系统认为是常量所以不允许修改

 

    常量指针:
      表示不能重新再做指向更改,但也许可以修改它指向的对象的值,这取决于它指向的值是变量还是常量 如下:

      const int a = 123 ;

      int b = 456 ;

      int  *const cur1 = &a ; // 此时不允许允许 *cur = 789,因为指向了一个常量
      int  *const cur2 = &b ; // 此时允许允许 *cur = 789,因为指向了一个变量
      cur1 = &b ;    //  错误,不允许更改指针的指向

      需要注意的是这类指针在定义时必须初始化。

    
     如果我定义了这样一个指针
     const int  *const cur = &a;
     那么既不能更改指向的数据值,也不能重新指向其他数据

 

 4.3 c风格字符串

    前面内容了解了char 数组可以表示c风格字符串,既然数组可以用指针表示那么char*也可以表示c风格串

    char a[]{'a','b','c','\0'} ;  // 第一种数组定义语法

    char a[] = “abc” ;  // 第2种数组定义语法

    char *a = “abc” ;  // 指针表示法

   

    c风格的字符串有多个操作函数: strlen(), strcpy(),strcat()以及strcmp()

    函数中所说的结束标示NULL实际上就是最后一个字符 '\0' 。

char s1[10] = {'m','o','b','i','l'};
char s2[20] = {'A','N','S','I','\0','C','+','+'};   
char s3[6]  = {'I','S','O','C','+','+'};
    
cout<<strlen(s1)<<endl; // 5

cout<<strlen(s2)<<endl; // 4
cout<<strlen(s3)<<endl; // 不确定

    strlen(s1)==5,原因是{'m','o','b','i','l'};指定一部分内容的时候,剩余部分会自动赋值为空字符,而'\0'是转义字符表示的就是空字符.
    strlen(s2)==4,因为第五个字符是字符串结束符'\0'(==0)。
    strlen(s3)==?,因为他没有结束符。

    string类型可以通过c_str()函数(返回的指针指向const char类型的是数组)转变为C风格字符串。

    const char *str = str2.c_str();

 

    可以创建动态数组,动态数组创建时更具类型不同其初始化值也不同。

// 内置类型
int *a = new int[10] ; // 包含10个未初始化元素的数组

int *b = new int[10]() ; // 包含10个初始化为0的元素数组

// 类类型

string *c = new string[10] ; // 包含10个调用了类默认构造函数完成初始化的元素数组

    可以看到内置类型需要在后面加上()才可以让元素初始化。

 

    动态数组定义之后一定要手动删除掉,否则会造成内存泄露

    delete [] a ; //  方括号必不可少,表示要释放一个动态数组

第5章表达式略过。

第6章语句略过。

posted @ 2012-12-23 12:32  Sam.Sun  阅读(180)  评论(0编辑  收藏  举报