21天学通C++_Day02——指针专题

8.1 什么是指针

指针是存储内存地址的变量,与所有变量一样, 指针也占用内存空间,在下图中,其地址为0x101,指针的值被解读为内存地址。
在这里插入图片描述

8.1.1 指针的初始化

指针需要初始化,否则会指向为随机地址。指针初始化代码如下:

int *pointToInt = NULL;

8.1.2 使用引用运算符(&)获取变量的地址

&变量名 是存储该变量的内存的地址。例如:

int age = 30;
cout << "Integer age is located at: 0x" << &age << endl;

结果如下:
Integer age is located at: 0x0000007F08CFFAB4

8.1.3 使用指针存储地址

代码如下:

int age = 30;
int* pointToInt = &age;
cout << hex << pointToInt << endl;   //hex是让输出值16进制显示

给上面的指针重新赋值,让其指向另一个变量。

int age = 30;
int* pointToInt = &age;
cout << hex << pointToInt << endl;

int dog = 9;
pointToInt = &dog;
cout << hex << pointToInt << endl;

结果如下:
0000002AA7EFF9E4
0000002AA7EFFA24

8.1.4 使用解除引用运算符(*)访问指针指向的数据

代码如下:

int age = 30;
int* pointToInt = &age;
cout << hex << pointToInt << endl;
cout << dec << *pointToInt << endl;   //dec是十进制

int dog = 9;
pointToInt = &dog;
cout << hex << pointToInt << endl;
cout << dec << *pointToInt << endl;

结果如下:
00000003525AF954
30
00000003525AF994
9
使用解引用运算符操纵指针:

int age = 30;
int* pointToInt = &age;
cout << hex << pointToInt << endl;
cout << dec << *pointToInt << endl;

cin >> *pointToInt;

cout << hex << pointToInt << endl;
cout << dec << *pointToInt << endl;
cout << age << endl;

结果如下:
00000068AAF1F5E4
30
10
00000068AAF1F5E4
10
10
在修改了*pointToInt之后,指针pointToInt值不变,*pointToInt变了,说明指向的值变了。

8.1.5 sizeof()用于指针

cout << hex << pointToInt << endl;
cout << dec << *pointToInt << endl;
cout << age << endl;
cout << "sizeof fundamental types -" << endl;
cout << "sizeof (char) = " << sizeof(char) << endl;
cout << "sizeof (int) = "  << sizeof(int) << endl;
cout << "sizeof (double) ="<< sizeof (double) << endl;
cout << "sizeof pointers to fundamental types -" << endl;
cout << "sizeof (char*) = "<< sizeof(char*) << endl;
cout << "sizeof (int*) = " << sizeof(int*) << endl;
cout << "sizeof (double*) = " << sizeof(double*) << endl;

结果如下:
sizeof fundamental types -
sizeof (char) = 1
sizeof (int) = 4
sizeof (double) =8
sizeof pointers to fundamental types -
sizeof (char*) = 8
sizeof (int*) = 8
sizeof (double*) = 8

8.2 动态内存分配

8.2.1 使用new和delete动态地分配和释放内存

使用new可以分配新的内存空间。如果成功,new将返回指向一个指针;使用new时,需要指定要为哪种数据类型分配内存:

  1. 分配单个内存:
    语法: Type* Pointer = new Type;
    delete Pointer;
  2. 分配多个内存:
    语法: Type* Pointer = new Type[num];
    delete[] Pointer;
    代码如下:
int* pointToAnAge = new int;
cin >> *pointToAnAge;
cout << "Age " << *pointToAnAge << "is stored at 0x" << hex << pointToAnAge << endl;
delete pointToAnAge;

结果如下:
10
Age 10 is stored at 0x0000027120517180
分配多个内存代码 如下:

int num = 0;
cin >> num;

int* pointToAnAge = new int[num];
cout << "Age is stored at 0x" << hex << pointToAnAge << endl;
delete[] pointToAnAge;

结果如下:
10
Age is stored at 0x000001B46F87F0C0

8.2.2 将递增和递减运算符(++和–)用于指针运算

对指针pointToInt执行递增运算(pointToInt++),将导致它增加4个字节,即sizeof(int)。将++用于该指针相当于编译器,希望它指向下一个int。同理,使用–则导致指针减少4个字节。

int num = 0;
cin >> num;

int* pointToAnAge = new int[num];
for (int cnt = 0; cnt < num; ++cnt) {
	cin >> *(pointToAnAge + cnt);
}
for (int cnt = 0; cnt < num; ++cnt) {
	cout << *(pointToAnAge++) << " ";
}
pointToAnAge -= num;
delete[] pointToAnAge;

结果如下:
在这里插入图片描述

8.2.3 将关键字const用于指针

const指针有如下三种:

  1. 指针包含的地址是常量,不能修改,但可修改指针指向的数据:
int daysInMonth = 30;
int* const pDaysInMonth = &daysInMonth;
*pDaysInMonth = 31; // OK! Data pointed to can be changed
int daysInLunarMonth = 28;
pDaysInMonth = &daysInLunarMonth; // Not OK! Cannot change address!
  1. 指针指向的数据为常量,不能修改,但可以修改指针包含的地址,即指针可以指向其他地方:
int hoursInDay = 24;
const int* pointsToInt = &hoursInDay;
int monthsInYear = 12;
pointsToInt = &monthsInYear; // OK!
*pointsToInt = 13; // Not OK! Cannot change data being pointed to
int* newPointer = pointsToInt; // Not OK! Cannot assign const to non-const
  1. 指针包含的地址以及它指向的值都是常量,不能修改(这种组合最严格):
int hoursInDay = 24;
const int* const pHoursInDay = &hoursInDay;
*pHoursInDay = 25; // Not OK! Cannot change data being pointed to
int daysInMonth = 30;
pHoursInDay = &daysInMonth; // Not OK! Cannot change address

8.2.4 将指针传递给函数

void CalcArea(const double* const ptrPi, // const pointer to const data
	const double* const ptrRadius, //no changes allowed
	double *const ptrArea) // can change data pointed to
{
	if (ptrPi && ptrRadius && ptrArea)//检查指针合法性
	{
		*ptrArea = (*ptrPi) *  (*ptrRadius) * (*ptrArea);
	}
}

8.2.5 数组和指针的类似之处

当定义一个指向数组中第一个元素的指针时,存储在指针中的地址与数组第一个元素在内存中的地址相同。

int myNumbers[5];
int* pointToNums = myNumbers;

cout << "pointToNums = 0x" << hex << pointToNums << endl;
cout << "&myNumbers[0] = 0x" << hex << &myNumbers[0] << endl;
cout << "myNumbers[1] = " << *(pointToNums + 1) << endl;
cout << "myNumbers[1] = " << myNumbers[1] << endl;

结果如下:
pointToNums = 0x000000226370FB98
&myNumbers[0] = 0x000000226370FB98
myNumbers[1] = cccccccc
myNumbers[1] = cccccccc

8.2.6 使用*访问数组中的元素以及将数组运算符[]用于指针

const int ARRAY_LEN = 5;
// Static array of 5 integers, initialized
int myNumbers[ARRAY_LEN] = { 24, -1, 365, -999, 2011 };

// Pointer initialized to first element in array
int* pointToNums = myNumbers;

cout << "Display array using pointer syntax, operator*" << endl;
for (int index = 0; index < ARRAY_LEN; ++index)
	cout << "Element " << index << " = " << *(myNumbers + index) << endl;

cout << "Display array using ptr with array syntax, operator[]" << endl;
for (int index = 0; index < ARRAY_LEN; ++index)
	cout << "Element " << index << " = " << pointToNums[index] << endl;

结果如下:
Display array using pointer syntax, operator*
Element 0 = 24
Element 1 = -1
Element 2 = 365
Element 3 = -999
Element 4 = 2011
Display array using ptr with array syntax, operator[]
Element 0 = 24
Element 1 = -1
Element 2 = 365
Element 3 = -999
Element 4 = 2011

8.3 使用指针时常犯的编程错误

8.3.1 内存泄漏

int* pointToNums = new int[5]; // initial allocation
// use pointToNums
...
// forget to release using delete[] pointToNums;
...
// make another allocation and overwrite
pointToNums = new int[10]; // leaks the previously allocated memory
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值