C++学习日记(指针)

直白解释

指针:变量存放的地址
指针变量:用于存放另一个变量地址的变量
变量的地址就是指针,存放变量地址的变量就是指针变量

具体点

指针提供了对所指向对象的间接访问,其保存的是另一个对象的地址

在定义时 *:指明其是指针变量
&:取地址运算符,返回的是该对象的存储地址

指针的定义和初始化

定义:
1.基类型 *指针变量名 (星的位置左中右都可以)

int *pointer

注意:这里的指针变量名是pointer!!!地址存放在了pointer里(后续有解引符号的使用,所以不要搞混)

2.不同数据类型的指针变量在内存中所占的空间是不同的(在后面指针的操作中会有涉及),指针值加1意味着指针移动一个位置

3.一个指针变量只能指向一个类型的变量

double a;
int *pointer1;
pointer1=&a;//这样赋值是错误的

4.连续定义指针变量

int *pointer1,pointer2;//错误,pointer2只是一个int类型的变量
int *pointer1,*pointer2;//正确的连续定义方法

初始化:
1.指针变量在使用之前必须进行初始化,否则会出错,并且很难发现
字面值不能进行取地址操作
可以有以下几种定义方式

    int a = 10;
    int b = 10;
    int *pointer1 = &a;
    int *pointer2;
    pointer2 = &b;
    int pointer;
    pointer = &10; //wrong
    pointer1 = pointer2;

2.指针变量初始化为0值常量表达式的时候,表明该指针变量不指向任何对象。

    int *pointer1 = 0; //不指向任何对象,但已初始化
    int a = 0;
    int *pointer2;
    pointer2 = a; //不能将int类型变量赋值给指针变量
    const int b=0;
    int *pointer3 = b;  //right

3.指针变量只能初始化或赋值为同类型的变量地址或另一个指针变量;
void* 可保存任何类型对象的地址。

扫描二维码关注公众号,回复: 1538154 查看本文章

指针变量的使用

通过指针变量可以间接操纵其所指向的对象,对指针进行解引用也可以访问其所指向的对象。

&是取地址运算符,用于取对象的地址;
*是解引运算符,用于取指针变量所指向的内容。

使用*(解引用)修改的是指针所指向对象的值
不使用则修改的是指针变量本身。

&*pointer=&a
*&a=a

指针与引用

区别:
1.引用(&)总是指向某个对象,所以定义引用的时候没有进行初始化是错误的。
2.给引用(&)赋值修改的是该引用关联对象的值,而不是使引用与另一个对象关联;
也就是说,引用一经初始化则始终指向同一个特定的对象。

#include<iostream>
using namespace std;
void main()
{
    int a = 10;
    int b = 20;
    int &pointer1 = a;
    int &pointer2 = b;
    pointer1 = pointer2;
    cout << "a= " << a << endl;
    cout << "b= " << b << endl;
    cout << "pointer1= " << pointer1 << endl;
    cout << "pointer2= " << pointer2 << endl;
    system("pause");
}

这里pointer1 = pointer2修改了a的值,没有修改引用本身,所以赋值后两个引用还是分别指向原来指向的对象,但是所指向对象由于赋值操作发生了变化,a和b的值相等了,所以输出的结果都是20.

指针的操作

指针值表示的是一个内存地址,两个指针值不能相加,相减得到一个整型数,指针值加上或减去一个整数得到的是另一个指针值。

指针值加减整数这种操作大多用在数组这种连续而且同类型元素的序列空间中。数组名为起始地址,赋给指针后,通过指针加减整数即移动指针来对数组元素进行操作。

//指针减法
#include<iostream>
using namespace std;
void main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *p1 = a;
    int *p2 = &a[4];
    cout << "p2-p1 = ";
    cout << p2 - p1 << endl;
    cout << "p1-p2 = ";
    cout << p1 - p2 << endl;
    system("pause");
}

运行结果是
4
-4

两个指针相减的结果相当于其指向数组的下标值相减的结果。
即4-0和0-4;
如果指针指向同一个数组当中的元素,则可以进行比较。

指向指针的指针

数据类型 **指针变量名

二级指针,指向的是指针型的数据。

#include<iostream>
using namespace std;
void main()
{
    char *name[3] = { "China", "Japan", "England" };
    //name数组中的元素分别定义为指向三个字符串的指针
    char **p;            //定义指针的指针
    for (int i = 0; i < 3; i++)
    {
        p = name + i;       //将P指向name中的元素
        cout << "name[" << i << "] point to ";
        cout << *p << endl;   通过字符串首地址输出整个字符串
    }
    system("pause");
}

这里写图片描述
p是指向指针的指针变量,赋值语句使得p指向name数组的0号元素name[0],
*p是name[0]的值即China。

#include<iostream>
using namespace std;
void main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *num[5];
    for (int i = 0; i < 5; i++)
    {
        num[i] = &a[i];  //使num指针数组中的元素指向整型数组a中的元素
    }
    int **p;
    p = num;            //使得p指向指针数组num的首地址
    for (int j = 0; j < 5; j++)
    {
        cout << "num[" << j << "] point to ";
        cout << **p << endl;  //通过p输出数组a中的元素
        p++;
    }
    system("pause");
}

使用指针访问数组元素

数组元素的指针其实也是数组元素的地址。

pointer=&a[0] 等同于 pointer=a;
#include<iostream>
using namespace std;
void main()
{
    int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int *pointer;
    cout << "&a[0] = ";
    cout << &a[0] << endl;
    cout << "a = ";
    cout << a << endl;   //输出a代表的地址
    pointer = &a[2];     //将第三个元素的地址赋给指针
    cout << "*pointer = ";
    cout << *pointer << endl;
    pointer = a + 2;    //通过数组名将第三个元素的地址赋给指针
    cout << "*pointer = ";
    cout << *pointer << endl;
    system("pause");
}

这里写图片描述

一维数组与指针

如果指针变量pointer已经指向了数组中的一个元素,则pointer+1指向数组中的下一个元素。

若p=&a[0];  则p+i=a+i;a代表的是数组首元素的地址
*(p+i)=*(a+i)=a[i](即数组元素,是值)

使用下标法和数组名进行数组元素输入输出的效率是相同的,而使用指向数组初地址的指针则是效率最高的方法。

多维数组与指针

c++实际上是把多维数组当成一维数组来处理的。
例如a[3][4]:这是一个一维数组a[3],数组的三个元素分别是a[0].a[1].a[2],其中每个元素又是一个一维数组,例如a[0]又是一个包含a[0][0],a[0][1],a[0][2],a[0][3]共4个元素的数组。

a(数组名)代表了二维数组首元素的地址,这个元素是四个整型元素组成的一维数组,所以a代表的是首行的首地址。
同理,a+1代表第一行的首地址…

在一维数组中a[i]和(a+i)是等价的,所以在二维数组中,a[0]+1和(*(a+0)+1)是等价的,代表的值都是&a[0][1]。

*(a[i]+j) = *(*(a+i)+j) = a[i][j];
表示形式                     含义
a                          多维数组名称,数组首地址
a+i,&a[i]                  第i+1行的首地址
a[i],*(a+i)                第i+1行,第1列首地址
a[i]+j,*(a+i)+j,&a[i][j]   第i+1行,第j+1列首地址
**(a+i),*a[i]              第i+1行,第1列的值
*(a[i]+j),*(*(a+i)+j),a[i][j]   第i+1行,第j+1列的值

自定义指针变量的方式:

数据类型 (*指针名)【元素数目】
int ( *p)[3];

指针和字符串

//字符串用法及使用指针输出字符串
#include<iostream>
using namespace std;
void main()
{
    char str[] = "ABCDE";
    cout << str << endl;
    char *p;
    int i;
    p = str;
    cout << "1:";
    cout << p << endl;        //第一种方式输出
    cout << "2:";
    for (i = 0; *(p + i) != '\0'; i++)
        cout << *(p + i);              //第二种方式输出
    cout << endl;
    cout << "3:";
    for (i = 0; *p != '\0'; i++, p++)
        cout << *p;            //第三种方式输出
    cout << endl;
    system("pause");

}

这里写图片描述
关于第一种输出方法:

把问题略为简化:“定义的是指向字符的指针,为什么能输出整个字符串”?

在C++中,cout << p;中的p如果是字符型指针,就被解释为“从这个指针的值(地址)开始,一个字节接一个字节地把其内容按ASCII码对应的字符输出到终端,直到遇到’\0’停止,且不输出’\0’“。

猜你喜欢

转载自blog.csdn.net/michaelzzk/article/details/79794306
今日推荐