C++ premier Plus书之—C++指针,数组,指针算术

首先看一下c++里的动态创建数组

int* p_array = new int[10];

new运算符返回第一个元素的地址, 也就是会把数组的第一个元素的地址赋给指针p_array

当使用完new分配的内存时, 应该使用delete来释放他们:

delete[] p_array;

注意new分配内存的时候如果是[], delete的时候也需要加[]

动态创建数组相比与静态创建数组的区别是: 动态创建数组只有在需要的时候才会去真正申请内存空间

 

看一个简单的例子:

#include "iostream"
using namespace std;

int main() {
	// 通过new来分配的内存时动态加载的, 
	double* p_double = new double[3];
	// c++里可以将指针当做数组的名称一样使用, 来访问数组中的元素
	// 这是因为c++里数组本身就是用指针来处理的
	p_double[0] = 1.1;
	p_double[1] = 1.2;
	p_double[2] = 1.3;
	
	cout << "p_double[1] = " << p_double[1] << endl;
	// 下面的代码展示了指针和数组名的不同
	// 可以对指针进行加减操作, 相当于将指针向后/向前移动
	// 这行的+1 就相当于指针指向了数组的第二个元素
	// +1增加的量, 相当于指针指向的类型的字节数
	p_double = p_double + 1;
	cout << "Now p_double[0] = " << p_double[0] << endl;
	cout << "Now p_double[1] = " << p_double[1] << endl;
	// 之所以要-1后再释放数组空间, 是因为new的时候是3
	// 所以释放的时候也需要释放完全
	p_double = p_double - 1;
	delete [] p_double;
	return 0;
}

程序的运行结果:

c++允许对指针和整数相加, +1 的结果相当于在原来的基础上加上指针指向的对象所占的字节数

再看一个数组和指针相互关系的例子:

#include "iostream"
using namespace std;

int main(){
	double d_arr[] = {100.0, 200.0, 300.0};
	short s_arr[] = {1, 2, 3};
	
	// 两种将数组的首地址赋值给指针变量的方式
	// 1.将数组名赋值给指针变量
	double* p_d_arr = d_arr;
	// 2.将数组的第一个元素的首地址赋值给指针变量
	short* p_s_arr = &s_arr[0];
	
	cout << "p_d_arr = " << p_d_arr << ", *p_d_arr = " << *p_d_arr << endl;
	// 指针向后移动了8个字节, 也就是指向了数组的第二个元素
	p_d_arr = p_d_arr + 1;
	cout << "add 1 to the p_d_arr pointer : " << endl;
	cout << "p_d_arr = " << p_d_arr << ", *p_d_arr = " << *p_d_arr << endl;
	
	cout << "p_s_arr = " << p_s_arr << ", *p_s_arr = " << *p_s_arr << endl;
	p_s_arr = p_s_arr + 1;
	cout << "add 1 to the p_s_arr pointer : " << endl;
	cout << "p_s_arr = " << p_s_arr << ", *p_s_arr = " << *p_s_arr << endl;
	
	cout << "*********************************" << endl;
	cout << "s_arr[0] = " << s_arr[0] << ", s_arr[1] = " << s_arr[1] << endl;
	cout << "*s_arr = " << *s_arr << ", *(s_arr + 1) = " << *(s_arr + 1) << endl;
	
	cout << "size of d_arr = " << sizeof(d_arr) << endl;
	cout << "sizeof(p_d_arr) = " << sizeof(p_d_arr) << endl;
}

运行结果如下:

从程序的运行结果可以看出:

从运行结果可以看出:

  1. 一般情况下c++把数组名解释为数组的第一个元素的地址(10~12行代码)
  2. 如果arr是数组名, 那么arr[i] 被解释为*(arr + 1)
  3. p_d_arr = p_d_arr + 1运行情况就是将指针移动到数组的下一个元素的地址(在这里是向后移动了8个字节)
  4. 还可以看出s_arr [1] 等价于*( s_arr + 1), 也就是c++在遇到s_arr[1]的时候会相当于做了*(s_arr + 1)这种操作.
  5. 指针和数组名的区别就是数组名是常量, 而指针是可以修改指针的值的(也就是可以对指针进行加减等操作), 另外对数组名进行sizeof得到的是数组的长度, 而对指针进行sizeof得到的是指针的长度

再看一个更为详细的数组和指针的相互关系的demo:

#include "iostream"
using namespace std;

int main(){
	short s_arr[10] = {1, 2, 3};
	
	// 由于s_arr是数组名,也就是相当于指针, 指向数组的首地址
	cout << s_arr << endl;
	// 输出数组的第一个元素
	cout << s_arr[0] << endl;
	// s_arr相当于指针, *指针 也就是指针指向的地址里的元素
	cout << *s_arr << endl;
	// 数组第一个元素的地址
	cout << &s_arr[0] << endl;
	// 由于s_arr相当于指针所以&s_arr 相当于首元素的地址
	cout << &s_arr << endl;
	
	cout << "************" << endl;
	// 由于s_arr相当于指针, 而又指向的是short型数组
	// 因此+1相当于向后移动了两个字节
	cout << "s_arr + 1 = " << s_arr + 1 << endl;
	// &s_arr指向的是一个20个字节内存块的地址
	// 因此&s_arr + 1, 相当于加了20个字节的地址
	cout << "&s_arr + 1 = " << &s_arr + 1 << endl;
	
	cout << "*************" << endl;
	// 和&s_arr类似, 也就是p_short这个指针指向了一个20个字节内存块的地址
	short (*p_short)[10] = &s_arr;
	// p_short的地址和s_arr一样
	cout << "p_short = " << p_short << endl;
	// 输出s_arr地址
	cout << "&s_arr = " << &s_arr << endl;
	// 输出s_arr首元素的地址
	cout << "&s_arr[0] = " << &s_arr[0] << endl;
	// 输出s_arr首元素
	cout << "s_arr[0] = " << s_arr[0] << endl;
	// 由于p_short指向的是&s_arr, 因此*p_short 就和 s_arr一样
	cout << "(*p_short)[0] = " << (*p_short)[0] << endl;
	cout << "p_short + 1" << p_short + 1 << endl;
}

运行的结果为:

注意:数组名被解释为数组的第一个元素的地址, 而对数组名应用地址运算符(&)的时候, 得到的是整个数组的地址.

看上面的运行结果, 虽然说s_arr和&s_arr的地址相同, 但是代表的含义不同, s_arr代表的是数组首元素的地址, 而&s_arr代表的是一个20字节内存块的地址, 所以&s_arr + 1 实际加的是20个字节

猜你喜欢

转载自blog.csdn.net/c1392851600/article/details/84262016