一、指针
1、指针的定义
要理解指针,要明白何为地址,就要理解变量在计算机内存中的存储方式。定义一个变量,计算机会在内存中找到一块字节数符合的空间,将变量内容存储进去。而这块空间中第一个字节在内存中的编号即是我们口中的地址。而指针,就是用来存放地址的变量。
2、指针的定义
变量类型(要存储地址的变量的结构类型加)* 变量名
注意:
int* p, q;//p是指针,q不是。 int* p, * q;//这样p,q才都是指针。
通常与要存储对应变量的地址的变量相关,为对应变量结构类型后加*号。
故指针可以存储指针的地址,从而出现了多级指针。
void*类型的指针在作为函数形参时可以接收任意类型的指针。
特殊:
- 函数指针类型(函数返回类型( * 变量名)(形参类型名));
- 指针数组(数组单个变量的类型 * 变量名[ 数组元素的数量 ]);
- 数组指针:用来存放数组地址的指针,形式:变量类型(*指针名)[ ] 。
3、指针的赋值
指针只能用地址来赋值,“&”符号可以取出变量的地址,用来赋值对应类型指针。对于数组和函数,数组名代表首元素的地址,而要赋值数组指针,应用&数组名来赋值。函数名本身就是地址,可以直接用于函数指针的赋值。而多级指针,则用低一级指针的地址进行赋值。
注:函数名即是地址,等价于&函数名;数组名为首元素地址,不等价于&数组名
int a;//定义一个变量a;
int* p = &a;//p中存储的是变量a的地址
int** q = &p;//q中存储的是指针p的地址,而p是一级指针,故用二级指针q来存储
int b[10];//定义一个数组b
int(*p1)[10] ;//定义数组指针p1,本质上是一个指针
p1 = &b;//赋值
int* p2[10];//定义指针数组p2,本质上是一个数组
p2[0] = p;//对p2中的第一个元素赋值
4、指针的应用
先介绍“ * ”的作用,“ * ”为单目运算符,意思是解引用,被用来访问指针的值所表示的地址上的变量,也可以说直接访问地址上所代表的变量。而对于多级指针,可以运用多个*号来一步步解引用,找到最初的变量。
指针通常运用于当函数需传回不止一个值时,而函数指针的应用可以实现回调函数机制(使函数的形参之一为函数指针,就可以在函数中运用传入函数的指针)
注: 指针名[n] 等价于 *(指针名+n)
二维数组a中,a[0]代表第一行的数组,而a[0]+1代表第一行第二列元素的地址
二维数组传参时,函数形参的设计可以省略第一个[ ]中的值,但第二个不可省略
一维数组传参时,函数形参的设计可以不定义数组的大小
5、其他
const与指针的关系:
- const 类型 *变量名(可以改变指针的指向,不能改变指针指向的内容)
- 类型 * const变量名(可以改变指针指向的内容,不能改变指针的指向)
- const 类型 *const 变量名(指针的指向、指针指向的内容都不可以改变)
地址的大小: - 地址大小只由编译器决定;
- 32位编译器大小为4,64位编译器大小为8.
当sizeof()中为 指针-指针 时,返回值为两指针间的元素个数。
二、结构体
1、结构的定义
结构是一个自定义的变量结构类型,用struct 结构名{成员1,成员2,…};(注:成员为一个变量,类型可为原C语言中有的类型,也可以是自定义的结构类型。)来进行定义。
定义后的结构用来定义变量:
struct 结构名 变量名;//注:struct 不可省略
但明显这样运用结构显得过于繁琐,所以通常结构多与typedef联用。typedef函数可以用来声明一个已有的数据类型的新名字,简单的说就是给数据类型取别名。
基本形式:
typedef 原类型名 新类型名;
与结构联用后:typedef struct 结构名{
成员1;
成员2;
…
}新类型名;
typedef struct a {
int n[10];
int* p;
}jiegou;//jiegou就是对自定义结构类型a的重命名
int main() {
jiegou a;//用typedef声明后就可以直接用新类型名来定义变量,此时的jiegou就相当于struct a。
}
通常结构声明写在main函数之外,目的时确保该结构为全局声明,否则只能在main函数内使用该结构,称为局部声明。
2、结构变量的赋值
赋值时需对结构内对应成员赋值,所以需要用”.“符号来取成员,再进行赋值;而对于结构指针变量,则需要用”->“来表示结构变量中的成员。
typedef struct a {
int n[10];
int* p;
}lianbiao;
int main() {
lianbiao a, * aa;//a为结构变量;aa为结构指针变量
int b;
int* c = &b;
a.n[0] = 1;
a.p = c;//也可用&b进行赋值
aa->n[0] = 1;
aa->p = c;
}
运算优先级:” . “ > ” -> "
3、结构的应用
运用于函数传参,传参后会在函数内新建一个结构变量,用传来的值对结构变量进行初始化。
结构与数组相似,都包含着多个值,但数组中每个元素的数据类型必须相同,而结构不需要。
当一串数据需要捆绑在一起进行调用时,但类型不同,就是结构大显身手的时候。
例: 有一串数据如下:
张三 男 18岁
李四 男 15岁
王五 男 23岁
typedef struct a {
const char* name;
const char* sex;
int age;
}duixiang;
int main() {
duixiang a;
a.name = "张三";
a.sex = "男";
a.age = 18;
}
这样在运用岁数做比较在排序时,就能做到一次性做到排序,在移动时能够捆绑一起移动,减少了很多操作。