c语言拾遗01---指针基本概念

一.指针

       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的值一直都没有改变
      在这里插入图片描述
  • 有指针:有指针,在一个函数的内部根本改变外部的实参。
 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值