【概念】指针

一、概念

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

二、运算

假设 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 对象的地址。

/*******相与枕藉乎舟中,不知东方之既白*******/
原文地址:https://www.cnblogs.com/Mars-0603/p/14293788.html