指针
*表示指针,**表示指针的指针。
例如:int *a;这个语句声明了一个变量a,a的数据类型是int *,也就是整型变量的指针类型(如果不懂什么是指针,那这个问题就没有意义了)。也就是说 a的值是一个内存地址,在这个地址所在的内存空间中存放的是一个整型变量。再看:int **b;这个语句也声明了一个变量b,b的数据类型是int **,也就是整型变量的指针的指针类型(二级指针)。也就是说 b的值是一个内存地址,该地址所在的内存空间中存放的是一个整型变量的指针(一级指针,或许就是上面那个a的值)。
😄只能赋址,不能赋值
- 指针的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误
int a;
int *p;
p = &a;// 可以
p = 1;// 错误,因为类型不同,p是指针,1是整数
⚠不能通过指针来改变对应内存空间的值,例如以下代码:会执行失败
int *p;
*p = 2;
printf("%d", *p);
// 同理,通过函数的形式也是一样的
int test(int* b) {
*b = 2;
printf("%d", *b); // 打印a的实际值,即 1
return 1;
}
int main() {
int *p;
test(p);
}
打印指针的内存空间值
- 指针的打印,可以通过指针打印对应内存空间的值。
int a=1;
int *p =&a;
printf("%d",*p);// 打印a的实际值,即 1
printf("%x",p);// 打印p的地址值,十六进制,例如: 62fe14
cout<< p <<endl;// 打印p的地址值,十六进制,例如: 0x62fe14
int a = 1;
int *p = &a;
*p = 2;
printf("%d", *p); // 打印a的实际值,即 1
.和->的区别
c++中 . 和 -> 主要是用法上的不同。
1、A.B:A为类或结构体的;
2、A->B:A为“类或结构体”的指针;用于访问指针类型变量的成员。
说白了,就看A是不是指针:
- A不是指针:用.
- A是指针:用->
结构体
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
.主要用于访问类的成员,->主要用于类类型的指针访问的成员,而.运算符,主要用于类类型的对象访问类的成员。
举例
class A{
public:
int a;
}
A ma;
A *p = ma;
指针p应用->来访问成员a,比如p->a,而ma应使用.来访问,比如ma.a区别就在这里,凡是指针就使用->,对象就使用.运算符。
如果定义了一个结构体数组。
struct student
{
int age;
char name[100];
};
struct student array[3];
通过这个数组进行调用这个结构体中的成员的时候,只能使用"."而不能使用->。
如果要是让一个指针指向这个数组的话,可以使用->这个符号。
struct student *p = array;
p->age = 30;;
memcpy(p->name,"刘德华");
这样是可以的。
&符号和指针
&有两种用法,
- &在变量操作区,表示取地址符;
- &在变量定义区,表示起别名;
- $在函数参数区,表示修改实际指向;
方式1:&(变量)
注意:这个变量是正常的变量,而不是一个指针类型的变量。
指针 === 地址,指针就是一类变量类型。
啥意思?也就是指针也是变量,并且和普通的变量拥有了多种的变量类型。可以是int、float、double、long等等
并且float *pointer;这是一个指针变量,变量名是pointer,而不是*pointer。
下述会报错,&是取地址,那么&a就是一个地址(指针)嘛,报错是因为变量的类型和指针的类型对不上。
int a = 1;
float * pointer_1;
pointer_1 = &a;
那么也就是
&a === pointer_1
*&a === *pointer_1
*&a === a
下述定义方式中,只有a是指针变量。
int *a,b,c;
方式2:取别名
int &b=a
C++中 ,int &b = a 的含义为:定义一个整型引用变量b,并且让b引用整型变量a。通俗地讲:为整型变量a定义一个“别名”b。
在现实生活中,一个人有正式的名字(int a),也可以有绰号(int &b)。无论是正式名还是绰号,都是表示这个人!
int a=1;
int &b = a;
b=2;
printf("%d",a);// 结果为2
方式3:函参,我就是实参!
那么如果出现在函数参数中,则表明直接操作的是同一个对象,无论这个参数本身例如:
int test(int &b){
b = 2;
return 1;
}
int main(){
int a=1;
test(a);
printf("%d",a);// 结果为2
}
如果不带&,则说明操作的是一个形参,是一个复制品!!!
int test(int b){
b = 2;
return 1;
}
int main(){
int a=1;
test(a);
printf("%d",a);// 结果a为1,没有修改成功
}
那么如果参数本身是一个指针类型呢?一个道理!如下列代码,输出是一致的,说明传的是实参。
int changePointer(int* b){
int c;
b = &c;
return 1;
}
int main(){
int *a;
printf("%x",a);
changePointer(a);
printf("%x",a);
}
如果修改一下,在b前面加一个&符号,那么两次的输出结果不一致,说明修改成功了。
int changePointer(int* &b){...}
同理可以多看一个例子捏:
void test1(string s){
s="shit";
}
int main(){
string s{"test"};
test(s);
cout<<s<<endl;// test
}
void test(string &s){
s="shit";
}
int main(){
string s{"test"};
test(s);
cout<<s<<endl;// shit
}