通过指针可以间接地访问内存
int a = 2;
内存中地址0x006FFC4C存储了a变量的值2,我们通过a变量访问值2;也可以通过指针p存储a的地址0x006FFC4C,通过访问地址,再提取地址处的值。
数据类型 *指针变量名
如:
int a = 2;
int *p;
p = &a; //取址
cout << "a地址为:" << &a << endl << p << endl;
解引用:使用*p读取p指向的地址处的数据
*p = 1000;
cout << a << endl << *p << endl;
--------------------
1000
1000
//使用指针p找到a的内存并修改了内容
指针存储的是某数据的地址,如0x006FFC4C,在32位OS中占4字节,64位中占8字节.x86即32位
sizeof(int*),sizeof(char*),sizeof(double*)…均为4字节即32位。
int *p = NULL;
地址为0处。*p = 100;
会报错,p为空指针指向非法内存空间
int *p = (int*)0x1100
,访问权限受限,不能自己随意指定地址。
被const修饰的指针变量,指针指向可以改变,但是指向的地址的数据不能改变。
int a = 11, b = 12; const int *p = &a;
const修饰的是*p
*p = 13;
错误!指向的地址0x1100处的数据11被const限制,不能改变。
p = &b;
正确,p的指向由a地址变为b的地址。
const修饰的是p
指针的指向不能改,但是指向的地址的数据可以改。
int* const p = &a;
*p = 13;
正确
p = &b;
错误
PS const int* const p = &a;
既修饰指针又修饰常量,指向和数据均不可改。
//x86中long long 是8字节
long long a[6] = {1,2,3,4,5,6};
long long* p = a;
for (; p < a+6; p++) {
cout << p << " " << *p << endl ;
}
--------------------------------------
006FFAF8 1
006FFB00 2
006FFB08 3
006FFB10 4
006FFB18 5
006FFB20 6
是一个数组,里面每一个元素是指针,保存着其他变量的地址。
int* a[6];
也叫行指针,是一个指针,指向一个数组
int (*p)[10]
p是一个指针,指向一个长度为10的整型的一维数组
ps: []优先级高于*,因此要加上()。
当用数组指针遍历二维数组时:
int arr[2][3] = {1,2,3,4,5,6};
int (*p)[3] = arr;
for (int i = 0; i < 2;i++, p++) {
cout << p << endl;
}
p每次代表arr的一行,依次是arr[0],arr[1],每次p++都是跳过了arr的一行,即3个整型的空间。
void swap(int c, int d){
int temp = c;
c = d;
d = temp;
}
int main(){
int a = 1, b = 2;
swap(a, b);
cout << a << " " << b << endl;
}
-----------------------------------
1 2
此处将a,b的值传递给swap的形参,但是a,b实参的值不会随着c,d形参的值改变而改变
void swap(int* c, int* d){
int temp = *c;
*c = *d;
*d = temp;
}
int main(){
int a = 1, b = 2;
swap(&a, &b); //传递地址
cout << a << " " << b << endl;
}
-----------------------------------
2 1
双重指针指的是指向指针的指针。
首先预热一下
int a = 11;
int* p = &a;
int** p1 = &p;
cout << "p1 " << p1 << endl;
cout << "*p1 " << *p1 << endl;
cout << "p " << p << endl;
cout << "**p1 " << **p1 << endl;
cout << "*p " << *p << endl;
---------------------------
p1 0x2200
*p1 0x1100
p 0x1100
**p1 11
*p 11
双重指针与函数形参实参的例子:
函数modifyPointer实现将空指针num的指向一个新的分配空间(这可以直接进行指向但是为了练习双重指针,特意写了一个函数)
void modifyPointer(int* a){
a = (int*)malloc(4);
}
int main(){
int* num = NULL;
modifyPointer(num);
cout<<num<<" "<<*num;
}
----------------------------
报错,num 是 nullptr。
分析:
num空指针作为实参传递给形参指针a,这里是值传递,是将num的值0传递给a,然后a指向新分配的空间,即a的值为新地址,但是并没有改变num的指向。要通过形参改变实参num需要用双重指针:
void modifyPointer(int** a){
*a = (int*)malloc(4);
}
int main(){
int* num = NULL;
modifyPointer(&num);
cout<<num<<" "<<*num;
}
----------------------------
0x2200 -842150451
成功分配到地址
分析:
双重指针a指向num指针,a赋值为新的分配空间地址,即num值为新的分配空间地址,所以num为新分配的int随机数。