指针复习

1.指针和自由存储空间

计算机程序存储数据时必须跟踪3种基本属性:
1. 信息存储在何处
2. 存储的值是多少
3. 存储的信息是什么类型

另一种策略是:以指针为基础,指针是一个变量,其存储的是值的地址,而不是值本身。

指针与C++基本原理
面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段决策就好比度假时,选择参观哪些景点取决于天气和当时的心情;而编译阶段决策更像不管什么条件下,都坚持预先设定的日程安排。

例如对于数组,编译阶段决策就需要在编译阶段就确定数组的长度,所以我们需要为数组创建尽可能长的长度,而大多数时候,这个长度都是用不完的,会造成内存的浪费。而运行阶段决策就会解决这一问题,在运行阶段根据此时数组需要的长度来决定内存的大小。

关于如何在运行阶段决定数组的长度,C++采用的方法是,使用关键字new来请求正确数量的内存以及使用指针来跟踪新分配的内存的位置。

#include <iostream>

int main()
{
    using namespace std;
    int updates = 6;
    int *p_updates;

    p_updates = &updates;

    cout << "Values: updates = " << updates;
    cout << ", *p_updates = " << *p_updates << endl;

    cout << "Addresses : &updates = " << &updates;
    cout << ", p_updates = " << p_updates << endl;

    //use pointer to change value
    *p_updates = *p_updates + 1;
    cout << "Now updates = " << updates << endl;

    return 0;
}

输出为:

Values: updates = 6, *p_updates = 6
Addresses : &updates = 0x28ff08, p_updates = 0x28ff08
Now updates = 7

Process returned 0 (0x0)   execution time : 0.343 s
Press any key to continue.

1.1声明和初始化指针

声明

指针声明必须指定指针指向的数据的类型。因为不同的数据类型所占用的存储空间不一样。

例如下面的两种声明方式:
int *ptr;
将*放在了ptr的前面,强调的是*ptr是一个int类型的值

int* ptr;
将*放在了int的后面,强调的是int*是一种类型,是指向int的指针

但是:
int* p1, p2;
将创建一个指针(p1)和一个常规int变量(p2)。对每个指针变量名,都需要使用一个*

对于指向不同数据类型的指针,他们的长度是一样的,一般为2个或者4个字节,取决于计算机系统。

初始化

可以在声明语句中初始化指针。在这种情况下,被初始化的是指针,而不是它指向的值。即:

int higgens = 5;
int *pt = &higgens;

将pt(而不是*pt)的值设置为&higgens

也就是说上面的代码和下面的是等效的:

int higgens = 5;
int *pt;
pt = &higgens;

看下面这个例子:

#include <iostream>

int main()
{
    using namespace std;

    int i = 6;
    int *p_i = &i;
    cout << i << endl;
    cout << &i << endl;
    cout << p_i << endl;
    cout << *p_i << endl;

    int j = 9;
    *p_i = j;
    cout << i << endl;
    cout << &i << endl;
    cout << p_i << endl;
    cout << *p_i << endl;
    cout << &p_i << endl;

    int k = 12;
    p_i = &k;
    cout << i << endl;
    cout << &i << endl;
    cout << p_i << endl;
    cout << *p_i << endl;
    cout << &p_i << endl;

    return 0;
}

运行结果是:

6
0x28ff08
0x28ff08
6
0x28ff04

9
0x28ff08
0x28ff08
9
0x28ff04

9
0x28ff08
0x28ff00
12
0x28ff04


Process returned 0 (0x0)   execution time : 0.201 s
Press any key to continue.

1.2 指针的危险

在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。
一定要在对指针应用解除引用操作符(*)之前,将指针初始化为一个确定的,适当的地址,这是关于使用指针的金科玉律。

例如:

long *fellow;
*fellow = 223333;

这里,fellow是一个指针,但是计算机只为它分配了存储fellow值的内存,没有分配存储fellow所指向的数据即(*fellow)的内存。那么*fellow = 223333将被存储在哪里呢?我们不知道。由于fellow没有初始化,它可能有任何值。不管只是什么,程序都将它解释为存储223333的地址,如果fellow的值恰巧为1200,计算机将把数据存放在223333地址上,即使这恰巧是程序代码的地址。没有初始化的指针所指向的地址很可能并不是所要存储值的地方,这种错误可能会导致一些最隐匿,最难以跟踪的bug。

1.3 指针和数字

指针不是整数。
整数可以执行加减乘除的运算,而指针描述的是位置,将两个地址相乘没有任何意义。因此,不能简单地将整数赋值给指针。

例如:

int *pt;
pt = 0xB8000000;

这是错误的,正确方法是先将整数进行强制类型转换,然后再赋值给指针。如下:

int *pt;
pt = (int*)0xB8000000; //将0XB8000000强制类型转换为指向int的指针

1.4 使用new来分配内存

接下来分析指针如何实现重要的OOP技术——在程序运行时分配内存。

1.5 使用delete来释放内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青子实

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值