文章目录
一.指针
1.1 什么是指针变量:
- 存放变量地址的变量为指针变量
1.2 定义:
- 类名标识符 *指针变量名
int *p;
float *q;
- “ * ” 是一个说明符,用来说明这个变量是指针变量,不属于变量名的一部分
- 前面的类型标识符号表示指针变量所指向的变量类型,而且只能指向这种类型的变量
1.3 指针初始化:
- 先定义后初始化
// 定义int类型的变量a
int a = 10;
// 定义一个指针变量p
int *p;
// 将变量a的地址赋值给指针变量p,所以指针变量p指向变量a
p = &a;
- 定义的同时初始化
// 定义int类型的变量a
int a = 10;
// 定义一个指针变量p
// 并将变量a的地址赋值给指针变量p,所以指针变量p指向变量a
int *p = &a;
- 初始化注意:指针变量是用来存放变量地址的 不要给他随便一个常数 下面写法是错误的
int* p;
p = 200; // 这是错误的
二.指针运算符
2.1 给指针指向的变量赋值:
char a = 10;
printf("修改前,a的值:%d\n", a);
// 指针变量p指向变量a
char* p = &a;
// *p代表 :将9赋值给p的存储空间的地址指向的存储空间
* p = 9;
printf("修改后,a的值:%d", a);
2.2 取出指针所指向变量的值:
char a = 10;
char* p;
p = &a;
char value = *p;
printf("取出a的值:%d", value);
2.3 使用注意:
- 在指针没有指向确定的地址之前,不要对它所指向的内容赋值,下面的写法是错误:
int *p;
*p = 10; //这是错误的
- 指针变量指向一个确定的变量后再进行赋值,下面的写法才是正确的:
// 定义2个int型变量
int a = 6, b;
// 定义一个指向变量b的指针变量p
int *p;
p = &b;
// 将a的值赋值给变量b
*p = a;
2.4 指针的本质:
int age = 3;
int* p = &age;
*p = 30;
- 汇编指令
// 将3的值赋值给ebp-0c这个地址 ebp-0c存放的是age变量
mov dword ptr [ebp-0Ch],3
// 将age变量的地址赋值eax
lea eax,[ebp-0Ch]
// 将eax的值存放在ebp-18地址上*p=&age
mov dword ptr [ebp-18h],eax
// 将ebp-18地址上的值---age的地址 赋值eax
mov eax,dword ptr [ebp-18h]
// 将30赋值地址为eax的地址空间
mov dword ptr [eax],1Eh
三.指针用途
3.1 现在有个要求:
-
写一个函数swap,接收2个整型参数,功能是互换两个实参的值。
- 没有指针
1 void swap(char v1, char v2) {
2 printf("更换前:v1=%d, v2=%d\n", v1, v2);
3
4 // 定义一个中间变量
5 char temp;
6
7 // 交换v1和v2的值
8 temp = v1;
9 v1 = v2;
10 v2 = temp;
11
12 printf("更换后:v1=%d, v2=%d\n", v1, v2);
13 }
14
15 int main()
16 {
17 char a = 10, b = 9;
18 printf("更换前:a=%d, b=%d\n", a, b);
19
20 swap(a, b);
21
22 printf("更换后:a=%d, b=%d", a, b);
23 return 0;
24 }
虽然v1和v2的值被交换了,但是变量a和b的值根本就没有换过来。因为基本数据类型作为函数实参时,只是纯粹地将值传递给形参,形参的改变并不影响实参。
- 过程分析:
- 在20行,将变量a,b的值分别传递给了swap函数的两个形参v1,v2
- 在第8行,将v1的值赋值给了temp
- 在第9行中,将v2的值赋值给了v1
- 在第10行中,将temp的值赋值给了v2.就这样,v1和v2的值被交换了,但是a和b的值一直都没有改变
- 在20行,将变量a,b的值分别传递给了swap函数的两个形参v1,v2
- 有指针:有指针,在一个函数的内部根本改变外部的实参。
1 void swap(char *v1, char *v2) {
2 // 中间变量
3 char temp;
4
5 // 取出v1指向的变量的值
6 temp = *v1;
7
8 // 取出v2指向的变量的值,然后赋值给v1指向的变量
9 *v1 = *v2;
10
11 // 赋值给v2指向的变量
12 *v2 = temp;
13 }
14
15 int main()
16 {
17 char a = 10, b = 9;
18 printf("更换前:a=%d, b=%d\n", a, b);
19
20 swap(&a, &b);
21
22 printf("更换后:a=%d, b=%d", a, b);
23 return 0;
24 }
- 先注意第20行,传递是变量的地址。因此swap函数的形参v1指向了变量a,v2指向了变量b
- 第6行代码是取出v1指向的变量的值,也就是变量a的值:10,然后赋值给变量temp
- 第9行代码是取出v2指向的变量(变量b)的值,然后赋值给v1指向的变量(变量a)
- 第12行代码是将temp变量的值赋值给v2指向的变量(变量b)
3.2 指针大小和类型问题?
- 一个指针变量占用多少个字节的内存空间?占用的空间是否会跟随所指向变量的类型而改变?
在同一环境下,一个指针变量所占用的内存空间是固定的。比如,在16位环境下,任何一个指针变量都只占用2个字节,并不会随所指向变量的类型而改变。
- 既然每个指针变量所占用的内存空间都一样的,而且存储的都是地址,为何还要分类型?比如指向int类型的指针,指向char类型的指针?—通过指针类型 ,来确定指向空间的大小。int类型的指针,从指针位置读取4个字节的大小空间
1 int i = 2;
2 char c = 1;
3
4 // 定义一个指向char类型的指针
5 char *p = &c;
6
7 // 取出 1
8 printf("%d", *p);
- 如果我改一下第5行的代码,用一个本应该指向int类型变量的指针p,指向char类型的变量c
int *p = &c;// 取出来的值是513,c原来的值是1 为什么是513呢?
最初指针p知道变量c是char类型,所有会从这个地址读1个字节 就是1。但改为int 类型 就从指向的地址读取两个字节 转为十进制就是513