C-class Week2.Day8

指针

什么是指针:

​ 指针是一种特殊的数据类型,使用它可以定义指针变量,指针变量中储存的是整型数据,代表了内存的编号

​ 通过这个编号可以访问到对应的内存。

为什么使用指针:

​ 1、函数与函数之间是相互独立的,参数无法进行传递,又想要共享变量时

​ 传参是单项值传递

​ 使用数组还需要传递数组长度

​ 全局变量,但是不推荐容易和第三方库冲突,个数不宜多,当多个函数都用使用时还是可以使用。

函数命名空间是相互独立的,但是地址空间是同一个地方,所以指针可以解决这个问题

​ 2、因为函数传参是值传递(内存拷贝),当字节过多时效率过低,如果传递的是变量的地址,只需要

​ 传递4|8个字节取决于计算机位数。

​ 3、堆内存取名它不像stack、bss、data、让变量名与内存建议关系,只能使用指针来记录堆内存的地址编号

​ 从而使用该堆内存

如何使用指针:
定义:

​ 类型* 变量名_p; int* p;

注意:

​ 1、指针变量与普通变量的用法上有很大的区别,为了以示区分,建议在变量名后面加上 _p 。

​ 2、指针的类型决定了存储的是什么类型变量的地址,指针的类型决定了可以通过指针变量访问的字节数。

​ 3、一个* 只能定义一个指针变量

	int a1,a2,a3;
	int* p1,p2,p3;//p1是指针,p2,p3是int
	int *p1,*p2,*p3;//这样一来 p1,p2,p3都是指针变量

​ 4、指针变量与普通变量一样的是默认值是随机的,所以一般都要初始化NULL,代表空指针

赋值(引用):

​ 变量名_p = 地址;地址必须是一个有权限而且有意义的内存地址,如果给错了不会报错!

指向栈内存:
	int num;
	int* p =  #
    or
    int num;
    int* p = NULL;
    p = #
指向堆内存:
	int *p = NULL;
	p = malloc(4);
解引用:

​ *p 通过指针变量中的地址记录的内存编号来访问对应的内存,该过程会产生段错误,原因是存储了非法的内存编号。

​ 注意:访问的字节是由指针变量的类型决定的

​ *p = 1000 ;但是上诉如果给地址时错误了,这里给值就会报错

​ 练习1:实现一个变量交换的函数,调用它对一个数组进行排序。

	#include<stdio.h>

void swap(int* a,int* b)
{
    int num=0;
    num = *a; 
    *a = *b; 
    *b = num;
}

void show(int a[],int len)
{
    for(int i=0;i<len;i++)
    {   
        printf("%d ",a[i]);
    }   
}

int main(int argc,const char* argv[])
{
    int a[5]={0,2,1,3,4};
    for(int i=0;i<4;i++)
    {   
        for(int j=0;j<4;j++)
        {   
            if(a[j]>a[j+1])
            {   
                swap(&a[j],&a[j+1]);
            }   
        }   
    }   
    show(a,5);
    return 0;
}

注意:想要获取多个返回值,可以借助指针返回。

练习二:实现一个函数,计算两个整数的最大公约数(用return)、最小公倍数(指针返回)

使用指针需要注意的问题:
空指针:

​ 值是NULL的指针都是空指针、如果对空指针进行解引用立即产生段错误。

​ NULL也是一种错误标志、如果一个函数返回值是指针类型时,当函数执行出错可返回NULL表示函数执行出错。

​ NULL在绝大多数系统中都是0,在个别系统中是1。

	if(NULL == p)

	if(!p)
如何避免空指针带来的段错误:

使用来历不明的指针之前先做判断是不是空指针

​ 1、当函数的参数是指针时,别人传来的可能是空指针

​ 2、从函数获取返回值时,也可能获取到的空指针

野指针:

​ 指针的指向不确定的内存。

野指针解引用的危害:

​ 1、会产生段错误

​ 2、脏数据

​ 3、一切正常

​ 野指针的危害比空指针更严重、因为它无法判断出来,而且就算一切正常再一次运行还是有可能不通过,隐藏错误

​ 短时间不会报错

避免野指针:

​ 1、定义指针时一定要初始化

2、函数不要返回局部变量的地址!!!!!!!!!!!!!!!!!!

​ 3、指针指向的内存被释放后、指针变量立即置空 = NULL;

​ 4、在接受到指针时及时判断

指针的运算:

​ 指针变量里储存的是整形,理论上整型数据能使用的运算符号他都能用。但是绝大部分都是无意义的

​ 指针+n: 指针+指针类型的宽度*n 前进了n个元素

​ 指针-n: 指针- 指针类型的宽度*n 后退了n个元素

​ 指针-指针:指针和指针之前相隔了多少个此类型的宽度或者说有多少个元素 (指针-指针)/ 类型宽度

指针与const
const int*p; 保护指针指向的内存不被修改
int const *p;同上

int* const p;保护指针变量不会修改
const int* const p;保护内存和指针变量不会修改
int const* const p;同上
    
这些类型限定符始终都遵循着---就近原则---

​ 为了提高传参效率而使用指针时,传参的效率虽然提高了,但是变量也有被修改的风险。换句话说你把你家钥匙给了别人 谁都能进

这种写法就可以保护指针变量所指向的值不被修改,钥匙给了但是进不去哈哈

小结分析
int swap(int* a,int* b)
{
    int c;
    if(*a<*b)//这里比较的是两个值的大小!
    {   
        c = *a; 
        *a = *b; 
        *b = c;
     }  
}int swap(int* a,int* b)
{
    int c;
    if(a<b)//这里表示的是两个值的储存位置门牌号,按照系统的规则这是一个永远成立的条件,因为b定义在了a后面所以永远b>a
    {   
        c = *a; 
        *a = *b; 
        *b = c;
        
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值