目录
-
指针
-
空指针
- new 运算符
- delete 运算符
- 指针与数组
- 一道题
- 指针与字符串,
11`
cout
11` - 指针与结构体
指针
- int* 是一种类型—指向 int 的指针。
- int* p1,p2 注意,该语句创建一个指针 p1 和一个 int 变量 p2。对于每个指针变量名,都需要使用一个 *。
- 在C++中创建指针时,计算机将分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。
- 一定要在对指针应用解除引用运算符(*)之前,将指针初始化为一个确定的、适当的地址。
- 指针加1,增加的量等于它指向的类型的所占字节数
空指针
C++98中,字面值0有两个含义:1.数字零;2.空指针
C++11引入新关键字 nullptr,来表示空指针
new 运算符
-
在运行阶段分配未命名的内存以存储值
-
在编译阶段给变量分配内存被称为静态联编(static binding);使用 new ,在运行阶段看需要分配内存,这是动态联编(dynamic binding)。
1
2
3 1int * p = new int;
2
3
- new int告诉程序,需要适合存储 int 的内存。new 运算符根据类型来确定需要多少字节的内存。然后,它找到这样的内存,并返回其地址,将地址赋给 p ,p 是被声明为指向 int 的指针。
- new 从堆(heap)或自由存储区(free store)的内存区域分配内存。
delete 运算符
1
2
3
4
5 1int * p = new int;
2...
3delete p;
4
5
-
这将释放 p 指向的内存,但不会删除指针 p 本身,仍然可以将 p 重新指向另一个新分配的内存块。
-
一定要配对的使用 new , delete ,否则将发生内存泄漏,即被分配的内存再也无法使用。
-
不要释放同一个内存块两次。
-
对空指针应用 delete 是安全的。
-
对于动态数组的操作略有不同:
-
delete[] 与使用 new[] 初始化的指针和空指针都兼容。
1
2
3
4 1 int * p = new int [10];
2 delete [] p;
3
4
new返回第一个元素的地址。
指针与数组
1
2
3
4 1int * p [5];
2int (*p)[5];
3
4
- 这是指针数组与数组指针的区别:
- 先看 int* p[5] 由于*是自右向左结合的,所以首先它是一个数组,然后是int*类型的,所以 int* p[ ] 是一个存放指针类型的数组(即:存放 int 类型变量的地址的数组);
- 再看int (*p)[5],首先()的优先级比*高,所以 p 是一个指针即地址,然后从这个地址开始以 sizeof(int)*5 分配存储连续的空间,相当于p是一个指向数组名(定指针,固定地址)的指针,可以这么看:int array[5]; p = array; p的类型就是int (*p)[ ],即数组指针类型,即指向包含5个整型的数组。
- 如果 ar 是数组名,则 ar[i] 被解释为 *(ar + i) 。
一道题
1
2
3
4 1int array[5]={1,2,3,4,5};
2cout<<*(*(&array+1)-1);
3
4
会输出什么?
这道题答案是5。
解析:
*(*(&array+1)-1)里,
&array是取array的地址;
&array+1就是在array的地址的基础上向前跑4*5个字节;
*(&array+1) 就是在数组末尾再往后一个字节的地址;
*(&array+1)-1 就是数组末尾的地址;
*(*(&array+1)-1) 就是数组末尾的那个元素。
指针与字符串,cout
在 cout 和多数C++表达式中,char 数组名、char 指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。
1
2
3
4 1char flower[10] = "rose";
2cout << flower << "s are red\n";
3
4
上述程序输出roses are red,但不会将整个字符串发送给 cout ,而只是发送该字符串的地址。
- 一般来说,如果给 cout 提供一个指针,它将打印地址。
- 但如果指针的类型是 char *,则 cout 将显示指向的字符串。
- 如果要显示的是字符串的地址,则必须将这种指针强制转换为另一种指针类型,如
(int *)flower
指针与结构体
通过使用 new,可以创建动态结构。创建动态结构时,不能将成员运算符句点(.)用于结构名,因为这种结构没有名称,只是知道它的地址。要使用箭头成员运算符(->)