• 【概念】指针


    一、概念

    指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。

    二、运算

    假设 ptr 是一个指向地址 1000 的整型指针,是一个 32 位的整数,让我们对该指针执行下列的算术运算:

    ptr++

    在执行完上述的运算之后,ptr 将指向位置 1004,因为 ptr 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果 ptr 指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。

    三、空指针

    赋为 NULL 值的指针被称为空指针。 NULL 指针是一个定义在标准库中的值为零的常量。即执行

    int  *ptr = NULL;

    ptr = 0。

    四、与数组

    (1)我们喜欢在程序中使用指针代替数组,因为变量指针可以递增,而数组不能递增,因为数组是一个常量指针。

    short int height[10]; //int型的数组(short int 每个数据2字节)
    cout <<  "height       "<< height << endl 
         <<  "height+1     "<< height + 1 << endl
         <<  "&height[0]   " <<  &height[0] << endl
         <<  "&height+1    "<< &height + 1<< endl
         <<  "height+9     "<< height+9 << endl
         << "height+10    " << height + 10 << endl;

    结果如下:

    height       0136F900
    height+1     0136F902
    &height[0]   0136F900
    &height+1    0136F914
    height+9     0136F912
    height+10    0136F914

    可以看到:

    • height 与 &height[0] 值相等。
    • height+1 = height + 2 字节 = height + 1 个 short int 也即 一个数组元素。
    • height+9 为 height[] 中最后一个元素的地址,height+10 为该数组结束后的第一个地址。
    • &height +1=height+10,即执行 &height+1 的结果是地址跳到整个数组之后第一个地址。

    (2)指针和数组并不是完全互换的。例如,请看下面的程序:

     1 #include <iostream>
     2  
     3 using namespace std;
     4 const int MAX = 3;
     5  
     6 int main ()
     7 {
     8    int  var[MAX] = {10, 100, 200};
     9  
    10    for (int i = 0; i < MAX; i++)
    11    {
    12       *var = i;    // 这是正确的语法
    13       var++;       // 这是不正确的
    14    }
    15    return 0;
    16 }

    把指针运算符 * 应用到 var 上是完全可以的,但修改 var 的值是非法的。这是因为 var 是一个指向数组开头的常量,不能作为左值。

    由于一个数组名对应一个指针常量,只要不改变数组的值,仍然可以用指针形式的表达式。例如,下面是一个有效的语句,把 var[2] 赋值为 500:

    *(var + 2) = 500;//地址没有改变

    再例如:
    cout << *(var++) << endl;    //编译错误,因为var是数组名(也是数组首元素地址),不是一个变量,不可修改其值
    cout << *(var+i << endl; //编译正确,因为没有对var进行赋值,只是通过与i相加访问变量地址

    (3)一维动态数组

    定义方式

    type* arrayname = new type [size](); // size可以是变量

    访问与赋值方式:

    for(int i=0;i<size;i++){
        *(arrayname+i)=i; // 或是 arrayname[i];
        cout<<*(arrayname+i)<<"
    ";
    }

    释放数组的方式:

    delete [] arrayname;

    (4)字符型指针数组

    char *names[MAX] 含义为:指针数组,即数组的每个元素都是一个指向 char 类型元素的指针。

    这个数组的每个元素被赋值了一个字符串,显然这个元素必然为一个指向 char 类型数组的指针;

    简单说,char *names[MAX] 中的元素是指向四个 char 类型数组的指针 names[i]。

     1     const char *names[MAX] = {"sun", "bin", "sunbin"};
     2     for (int i = 0; i < MAX; i++)
     3     {
     4         cout << "Value of names[" << i << "] = ";//输出字符串的值 sun
     5         cout << names[i] << endl;
     6         cout << "Value of *names[" << i << "] = ";//输出指针所指向字符串的第1个字符 s
     7         cout << *names[i] << endl;
     8         cout << "Value of *names[" << i << "]+1 = ";//输出ascii码值 116
     9         cout << *names[i] + 1 << endl;
    10         cout << "Value of *(names[" << i << "]+1) = ";//输出指针所指向字符串的第2个字符 u
    11         cout << *(names[i] + 1) << endl;
    12     }

    int *ptr[3];

    由于 C++ 运算符的优先级中,* 小于 [],所以 ptr 先和 [] 结合成为数组,然后再和 int * 结合形成数组的元素类型是 int * 类型,得到一个叫一个数组的元素是指针,简称指针数组。

    等价于int *(ptr[3]);

    int (*ptr)[3];

    这个就不一样了,优先级顺序是 * 小于 (),() 等于 [],() 和 [] 的优先级一样,但是结合顺序是从左到右,所以先是 () 里的 * 和 ptr 结合成为一个指针,然后是 (*ptr) 和 [] 相结合成为一个数组,最后叫一个指针 ptr 指向一个数组,简称数组指针。

    (5)函数传参及返回值

     1 #include<iostream>
     2 
     3 using namespace std;
     4 
     5 int get(int *p)
     6 {
     7     *p = 5;
     8     return *p;
     9 }
    10 
    11 int main()
    12 {
    13     int a = 0;
    14     get(&a);
    15     cout << a << endl;
    16     return 0;
    17 }
     1 #include <iostream>
     2 #include <ctime>
     3 #include <cstdlib>
     4  
     5 using namespace std;
     6  
     7 // 要生成和返回随机数的函数
     8 int * getRandom( )
     9 {
    10   static int  r[10];
    11  
    12   // 设置种子
    13   srand( (unsigned)time( NULL ) );
    14   for (int i = 0; i < 10; ++i)
    15   {
    16     r[i] = rand();
    17     cout << r[i] << endl;
    18   }
    19  
    20   return r;
    21 }
    22  
    23 // 要调用上面定义函数的主函数
    24 int main ()
    25 {
    26    // 一个指向整数的指针
    27    int *p;
    28  
    29    p = getRandom();
    30    for ( int i = 0; i < 10; i++ )
    31    {
    32        cout << "*(p + " << i << ") : ";
    33        cout << *(p + i) << endl;
    34    }
    35  
    36    return 0;
    37 }

    (6)this指针

    在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。

    友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。

    静态成员函数没有 this 指针,也不能访问类的 this 指针。

    1 class Box{
    2     public:
    3         Box(){;}
    4         ~Box(){;}
    5         Box* get_address()   //得到this的地址
    6         {
    7             return this;
    8         }
    9 };

    this 指针的类型可理解为 Box*

     1 int main(){
     2     
     3     Box box1;
     4     Box box2;
     5     // Box* 定义指针p接受对象box的get_address()成员函数的返回值,并打印
     6     
     7     Box* p = box1.get_address();  
     8     cout << p << endl;
     9     
    10     p = box2.get_address();
    11     cout << p << endl; 
    12 
    13     return 0;
    14 }

    此时得到两个地址分别为 box1 和 box2 对象的地址。

    /*******相与枕藉乎舟中,不知东方之既白*******/
  • 相关阅读:
    【iOS】ARC & MRC
    【iOS】判断苹果的设备是哪种
    【iOS】获取项目名和版本号
    CSDN Markdown 超链接
    【iOS】安装 CocoaPods
    【Android Studio】常用快捷键
    Linux初接触设置笔记01
    Java循环输出一个菱形与阶乘倒数
    对象的声明与实例化(转)
    Java堆/栈/常量池以及String的详细详解(转)------经典易懂系统
  • 原文地址:https://www.cnblogs.com/Mars-0603/p/14293788.html
Copyright © 2020-2023  润新知