指针

注意

int x = 5;
int y = 15;

swap(&x,&y);

void swap(int *a,int *b){

// a的值就是&x a就是x的内存地址
// *a 表示x的值

}



取地址操作符

&变量名

int i = 10;
cout << "i内存地址:" << &i << endl;


变量定义


类型 * 指针变量名

int *pointer1, *pointer2;

float *pointer3;

char *pointer4;


上面pointer1、pointer2是指针变量名 ,在变量名前加*,表示该变量是指针变量

// 将变量i的内存地址存放到指针变量pointer1
pointer1 = &i;

// 输出在指针变量中存储的地址
cout << pointer1 << endl;

// 访问指针中地址的值
cout << *pointer1 << endl;

demo1

int *pointer1, *pointer2;
int i = 10;

pointer1 = &i;

cout << "i内存地址:" << &i << endl;
cout << "pointer1保存的内存地址:" << pointer1 << endl;
cout << "pointer1指针的值:" << *pointer1 << endl;

特殊的值NULL

没有初始化的指针变量是危险的。如果在声明变量之后,找不到合适的地址进行初始化。

在这里我们引入一个特殊的地址--NULL。它的意思是空,即指针没有指向任何东西。比如

int *empty = NULL;
// 打印00000000
cout << "empty address :" << empty << endl;

注意:c++是区分大小写敏感的,NULL和null是不同的。所以在使用是必须大写。

*又称为间接引用操作符。其作用是获取指针所指向的变量或存储空间。间接引用的指针可以作为左值。

*指针变量名

demo2

int* pointer1, * pointer2;
int i = 10;

pointer1 = &i;

cout << "i内存地址:" << &i << endl;
cout << "pointer1保存的内存地址-i的内存地址:" << pointer1 << endl;
cout << "pointer1指针的值-i的值:" << *pointer1 << endl;
cout << "pointer1指针自己内存地址:" << &pointer1 << endl;

int** iptriptr = &pointer1;
// pointer指针的内存地址
cout << "iptriptr保存的内存地址-pointer1的内存地址:" << iptriptr << endl;
// 这里"pointer1存储的是i的内存地址
cout << "iptriptr指针的值-pointer1的值=i的存储地址:" << *iptriptr << endl;

i内存地址:006FFACC

pointer1保存的内存地址-i的内存地址:006FFACC

pointer1指针的值-i的值:10

pointer1指针自己内存地址:006FFAE4

iptriptr保存的内存地址-pointer1的内存地址:006FFAE4

iptriptr指针的值-pointer1的值=i的存储地址:006FFACC


常量指针、指针常量


指针常量: 指针指向地址是一定的,但其内容可以修改  int *const p

常量指针: 指针可以指向其他地址,但是内容不可以改变 const int *p, int const *p

把*读作指针  const读作常量


int aa = 10;
const int bb = 18;

// 指针常量 指针指向地址不能改变,值可以变
int* const pc = &aa;
cout << *pc << " " << pc << endl;
*pc = bb;
cout << *pc << " " << pc << endl;
// 常量指针 值不能改变 address可以变
const int *cp = &aa;
cout << *cp << " " << cp << endl;
cp = &bb;
cout << *cp << " " << cp << endl;

delete

double * p3 = new double[3];
p3[0] = 0.2;
p3[1] = 0.5;
p3[2] = 0.8;

cout << "p3[1] is " << p3[1] << ".\n";
p3 = p3+1; // 指向下一个元素的地址 指向第2个元素而不是第一个元素
cout << "now p3[0] is " << p3[0] << " and ";
cout << "p3[1] is " << p3[1] << ".\n";

p3 = p3-1; //将指针指向原来的值
delete [] p3; // free the memory


return 0;

demo

double wages[3] = {10000.0,20000.0,30000.0};
short stack[3] = {3,2,1};

cout << "----------------------------------------" << endl;

//pw声明只想double类型的指针,然后将它初始化为wages数组种的第一个元素的地址
double *pw = wages;
short *ps = &stack[0];
cout << "pw= " << pw << ",*pw= " << *pw <<endl;
pw=pw+1;
cout << "add 1 to the pw pointer:\n";
cout << "pw="<< pw << ",pw=" << *pw << "\n\n";
cout << "ps=" << ps << ",*ps=" << *ps << endl;
ps = ps+1;
cout << "add 1 to the ps pointer:\n";
cout << "ps=" << ps << ",*ps=" << *ps << "\n\n";

cout << "access two elements with array notation\n";
cout << "stack[0]=" << stack[0] << ",stack[1]=" << stack[1] << endl;

//stack[1]看作是*(stack+1),这意味着先计算数组第2个元素的地址,然后找到存储在哪里的值
cout << "access two elements with pointer notation\n";
cout << "*stack="<< *stack << ",*(stack+1)=" << *(stack+1) << endl;

cout << sizeof(wages) << " = size of wages array\n";
cout << sizeof(pw) << " = size of pw pointer \n";

cout << "----------------------------------------" << endl;

函数指针


函数返回值类型 (* 指针变量名) (函数参数列表);


#include <stdio.h>

int max(int x,int y);

int main(){

int (*p)(int a,int b);
int a, b, c;
//把函数max赋给指针变量p, 使p指向max函数
p = max;

printf("please enter a and b:");
scanf("%d%d", &a, &b);
c = (*p)(a,b); //通过函数指针调用max函数
printf("a = %d\nb = %d\nmax = %d\n", a, b, c);

return 0;

}

//定义max函数
int max(int x, int y) {
if (x >= y) {
return x;
}
else {
return y;
}

}

指针函数

//声明指针函数

int *add(int a,int b);

int main(){
int a = 5;
int b = 3;

//调用指针函数
int *c = add(a,b);
cout << "c.address="<< c<< endl;

return 0;
}

//定义指针函数
int *add(int a,int b){
int c=a+b;
// 返回变量c的内存地址
return &c;

}

demo

Animal animal;

animal.sleep();

Animal *a = new Animal;
a->age = 18;
a->setId(20);

cout << "getAge=" << a->getAge() << endl;
cout << "getId=" << a->getId() << endl;


打印指针地址

short dates[SS];
short * pti;
short index;
double bills[SS];
double * ptf;
pti = dates;
ptf = bills;

for(index =0; index<SS;index++) {
// 打印指针地址
printf("pointers.address=%p ptf.address=%p\n",pti+index,ptf+index);
}


pointers.address=000000000061FDFE  ptf.address=000000000061FDD0
pointers.address=000000000061FE00  ptf.address=000000000061FDD8
pointers.address=000000000061FE02  ptf.address=000000000061FDE0
pointers.address=000000000061FE04  ptf.address=000000000061FDE8
pointers.address=000000000061FE06  ptf.address=000000000061FDF0


dates+2 == &dates[2]  // 相同地址

*(dates+2) == dates[2] //相同值

*(dates+2) // 第3个元素

*dates + 2 // 第1个元素的值+2