1,指针
表示内存地址(指针指向了内存地址)
如果这个内存地址恰好是某个变量的地址,俺么又称“这个指针指向该变量”
只要在变量前面加上&,就表示变量的地址
2,指针变量
指针变量用来存放指针(地址)
⚠️:一般把星号放在数据类型之后(C++程序员),星号是类型的一部分。
给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量。
eg,
int a;
int* p=&a;
p保存的是地址,*p是这个地址存放的元素;
指针变量支持自增和自减操作,对于int*类型的指针变量p来说,p+1是指p所指的int变量的下一个int类型变量地址;
对于指针变量,把其存储的地址类型称为基类型,例如定义为int* p的指针变量,int就是它的基类型。
⚠️:基类型必须和指针变量存储的地址类型相同,也就是上面定义的指针变量p不能存放double或char类型数据的地址,而必须是int类型数据的地址。
3,指针与数组
数组名可以作为数组的首地址使用
eg,
int a[10]={1};
int* p=a;
a作为数组a的首地址&a[0]而被赋值给指针变量p
由于指针变量可以进行加减法,即a+i等同于&a[i];
如果想要访问其中的元素a[i],需要加上星号,使其变成*(a+i)后才和a[i]等价
输入数组元素的新颖写法:
scanf(“%d”,a+i);
两个int类型的指针相减,等价于在求两个指针之间相差了几个int
4,使用指针变量作为函数参数
这时视为把变量的地址传入函数,如果在函数中对这个地址的元素进行改变,原先的数据就会确实地改变
在上述代码中,把int型的指针变量p赋值为a的地址,然后通过change函数把指针变量作为参数传入,此时传入的其实是a的地址,在change函数中,使用*p修改地址中存放的数据,也就是改变了a本身,当最后输入a时,就已经是改变了的值,这种传递方式被称为地址传递。
⚠️:函数在接收参数的过程中是单向一次性的值传递。
只有在获取地址的情况下对元素进行操作,才能真正地修改变量。
5,引用
引用不产生副本,而是给变量起了别名。
对引用变量的操作就是对原变量的操作。
引用只需要在函数的参数类型后面加上&就可以了。(一般写在变量名的前面)
⚠️:要把引用跟取地址运算符&区分开来,引用并不是取地址的意思。
区分:
引用:
1,在等号左边
2,与类型在一起
3,定义的时候必须初始化
4,&后面跟的别名是新名字,之前不存在
取地址:
1,在等号右边
2,与变量在一起
3,&后面跟的变量,已经存在
eg,
int a=3;
int &b=a; //引用
int* p=&a; //取地址
指针变量其实是unsigned类型的整数,因此为了理解方便,可以“简单”地把*int类型理解为unsigned int类型,而直接交换这样的两个整型变量是需要加引用的
6,结构体的使用
结构体的定义:
格式
struct Name{
//一些基本的数据结构或者自定义的数据类型
};
eg,
struct studentInfo{
int id;
char gender; //‘F’ or ‘M’
char name[20];
}Alice,Bob,stu[1000];
结构体变量和结构体数组,也可以按照基本数组类型(如int型)那样定义
studentInfo Alice;
studentInfo stu[1000];
结构体里面定义出了自身(这样会引起循环定义的问题)之外的任何数据类型,虽然不能定义自身,但是可以定义自身类型的指针变量
eg,
struct node{
node n; //不能定义node型变量
node* next; //可以定义node*型指针变量
};
7,访问结构体内的元素
“.”操作和”->”操作
eg,
struct studentInfo{
int id;
char name[20];
studentInfo* next;
}stu,*p;
访问stu中变量的写法如下:
stu.id
stu.name
stu.next
访问指针变量p中元素的写法如下:
(*p).id
(*p).name
(*p).next
C语言中又有一种访问结构体指针变量内元素的更简洁的写法:
p->id
p->name
p->next
也可以对结构体变量进行赋值:
stu.id = 10086;
int getId =stu.id;
构造函数是用来初始化结构体的一种函数,它直接定义在结构体中。
一个特点是它不需要写返回类型,且函数名与结构体名相同。
对一个普通定义的结构体,其内部会生成一个默认的构造函数(但不可见)
struct studentInfo{
int id;
char gender;
// 默认生成的构造函数
studentInfo(){}
};
如果想要手动初始化参数,只需要提供初始化参数来对结构体内的变量进行赋值即可。
struct studentInfo{
int id;
char gender;
//下面的参数用以对结构体内部变量进行赋值
studnetInfo(int _id,char _gender){
id=_id;
gender=_gender;
}
};
构造函数也可以简化为一行;
struct studentInfo{
int id;
char gender;
studentInfo(int _id,char _gender) : id(_id),gender(_gender){ }
};
这样可以在需要时直接对结构体变量进行赋值:
studentInfo stu= studentInfo(10086,”M”);
⚠️:如果自己重新定义了构造函数,则不能不经初始化就定义结构体变量(也就是默认的生成的构造函数 studentInfo(){ } 已经被覆盖了)
为了既能记不初始化就定义结构体变量,又能享受初始化带来的便捷,可以吧”studentInfo(){}”手动加上
只要参数格式和类型不完全相同,就可以定义任意多个构造函数。