内存地址
内存的每一个字节分配一个编号,这个编号就是内存地址(唯一),内存中每一个数据都会对应相对的地址。
取址符 &。X86内存地址4字节(32位),X64内存地址8字节
int * p1, p2;
//p1 是int指针, p2是int变量
int *p3, *p4;
//p3, p4都是int指针
无论几级指针,保存的都是地址。保存的地址所指向的内存中保存的数据类型为 去掉一个 * 号后剩下的数据类型。
//空指针 C++
int * p = nullptr;
//c
int * p = NULL;
//悬挂指针 = 野指针
指针的宽度和跨度
- 宽度:指针所指内容的宽度取决于所指内容的类型
- 跨度:指针运算的跨度取决于所知内容的类型的大小
void 指针
- void * 可以指向任何类型变量,任何类型变量的指针都可以转为 void *
- void * 不能解引用和算术运算,必须先进行强转
const和指针
- const 在 * 左边:const type * p1; *p1只读,p1可读可写。即不可通过星号修改数据。
- const在* 右边:type * const p2; *p2可读可写,p2只读。即不可修改变量p2。
- const在* 左右都有:const type * const p3; *p3, p3只读。
数组和指针
- 指针数组(int数组、double数组)
- 数组指针(数组的指针)
#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int arr[5];
int *p1[5];
int (*p2)[5] = &arr;
//【5】不能去掉
cout << typeid(arr).name() << endl;
cout << typeid(p1).name() << " " << sizeof(p1) << endl;
cout << typeid(p2).name() << " " << sizeof(p2) << endl;
return 0;
}
//p1指针数组
//p2数组指针
/*输出结果
A5_i
A5_Pi 40
PA5_i 8
*/
char数组,cout时不会输出地址,而是输出字符串,int数组会输出地址。
字符串和指针
const char* str = "hello world!";
//str就是字符串指针
cout << sizeof(str) << endl;
//指针变量的大小
cout << (*str) << endl;
//h
cout << *(str + 1) << endl;
//e
char s[] = "hello world!";
//s++ X
const char* arr[4] = {"abc", "def", "hij", "klmn"};
//字符串指针数组
cout << *(arr[1] + 1) << endl;
//cout << *(A + 1) << endl;
函数指针
函数地址就是存储其机器语言代码的内存的开始地址。
函数名就是函数的地址。
returnType (* pf)(typeOfAgr1, typeOfAgr2, ...) = func;
//调用如下
(*pf)(a, b);
//不加括号类似函数声明
int* pf(int, int);
//这是一种返回值为 int* 类型的函数声明
函数指针常用于函数的回调。