算法笔记系列:2.7 指针 2.8 结构体的使用
2.7.1 什么是指针
-
指针用来表示内存地址,当一个指针指向一个变量,即指指针表示了该变量占用字节中第一个字节的地址
-
通过取地址运算符& 获取变量地址
-
指针是一个unsigned类型的整数
2.7.2 指针变量
-
指针变量用于存放指针
-
定义方式有下面两种
int* p=&a; int *p1,*p2;
-
当同事定义好几个相同类型的指针变量时,*号可以写在变量前面
-
但要注意的是指针变量始终是p,*号是类型的一部分
-
*p可以将指针变量p所指地址内的数据取出
# include<stdio.h> int main(){ int a; int* p=&a; a=233; printf("%d\n",*p);//加*号取出地址中的数据 printf("%d",p);//p输出为内存地址 return 0; } 输出: 233 6422036
-
p+1指P所指int型变量下一个int型变量的地址,这个下一个跨越1整个int,即4个字节,因此指针支持自增和自减,常用于数组中
-
2.7.3 指针与数组
-
数组名称也作为数组的首地址使用,即a==&a[0]
-
在数组中 a+i==&a[i]
-
指针的减法
# include<stdio.h> int main(){ int a[10]={1,3,5,7,9,10}; int* p=a; int* q=&a[5]; printf("q=%d\n",q); printf("p=%d\n",p); printf("q-p=%d",q-p);//地址的相减返回的差了几个int return 0; } 输出: q=6422004 p=6421984 q-p=5
2.7.4 使用指针变量作为函数参数
-
视为把变量的地址传入函数。如果在函数中对这个地址中的元素进行改变,原先的数据就会确实地被改变
-
基于上述原理,指针作为参数可以完成某些功能函数,本质上起到了在函数内部改变外部变量的作用。例如交换两个数
# include<stdio.h>
void swap(int* a,int* b){
int temp=*a;
*a=*b;
*b=temp;
}
int main(){
int a=1,b=2;
int *p1=&a,*p2=&b;
swap(p1,p2);//在获取地址的情况下对元素进行操作,才能真正地修改变量
printf("a=%d,b=%d",a,b);
return 0;
}
输出:
a=2,b=1
2.7.5 引用
-
在不使用指针的情况下,达到修改传入参数的目的,引用相当于给变量起个别名,不产生副本,指向同一个地址。于是对引用变量的操作就是对原变量的操作
-
使用方法:在定义函数时在参数类型后面或者变量名前面加个&就行
-
引用中的&不是取地址运算符,并不是取地址的意思
-
指针的引用 通过指针的引用可以将传入的地址交换来达到交换两个变量的效果
# include<stdio.h>
void swap(int* &p1,int* &p2){
int* temp=p1;
p1=p2;
p2=temp;
}
int main(){
int a=1,b=2;
int *p1=&a,*p2=&b;
swap(p1,p2);//引用是产生变量的别名,所以只能输入变量
printf("a=%d,b=%d\n",a,b);//a,b本身的地址没变,里面的值也没变,所以a,b没变
printf("a=%d,b=%d",*p1,*p2);//变得只是p1和p2两个指针指的地址交换了
return 0;
}
输出:
a=1,b=2
a=2,b=1
2.8.1 结构体的定义
- 定义基本格式
struct Name{
//一些基本的数据结构或者自定义的数据类型
};
- 可以在大括号外直接定义结构体变量,例如:
struct studentInfo{
int id;
char gender;
char name[20];
char major[20];
}Alice,Bob,stu[1000];//这里的stu[1000]定义了一个结构体数组
2.8.2 访问结构体内的元素
- “.”操作
- “->”操作
struct studentInfo{
int id;
char gender;
char name[20];
char major[20];
}stu,*p;
访问指针变量p中的元素的两种方法
1 (*p).id
2 p->id
2.8.3 结构体的初始化
-
利用构造函数进行初始化,构造函数名与结构体名相同
-
在自己重新定义构造函数之后,原来默认生成的构造函数就被覆盖了,为了能不初始化就定义结构体变量需要手动加上
-
一个结构体中可以定义多个构造函数,只要参数个数和类型不完全相同就行