C语言中有关指针入门的内容(包含了指针的定义,野指针,以及指针的运算,二级指针等内容)

目录

​​​​​1.指针的定义

2.野指针出现的原因以及如何避免写出野指针

3.指针间的运算

4.二级指针的表示以及使用

正文

             1.指针的介绍

      指针:是用来存放地址的变量(由于其为变量,因而可以对其进行加减【后文会有所涉及】)通过指针我们能找到内存单元

        例如

int main()
{  
  int a=0;  
  int *pa=&a;  //将a的地址放到了pa中,而*用于表示pa是一个地址,而int表示的则是a的指针类型
   *pa = 20;    //*可用于解引用 ,通过解引用pa (如*pa)可找到a,再将20赋予了a
  printf("%d",a)  //上一步赋予了a 20的值,因此a打印出来的值不再是0而是20
}

      指针的存储采用的十六进制可用1个16进制位表示4个二进制位)。

        例如  假设     int *a=0x11223344 (其中0x表示其为16进制,则有11223344   8个十六进制位的数组成,也就是可看成 8 *4=32 个二进制位(一个二进制位所占内存为1个比特位,8个比特位又组成一个字节,因此 a 的指针占了4个字节的空间。

       注:32位平台指针位4个字节,64位平台占8个字节。

       

  指针类型的含义

          1.指针类型决定了 解引用的权限有多大

                   例如 

int main( )
{
  int a =0; 
  char *a =&a;   //指针类型为char(1个字节)而a的为整形int(4个字节)
  *a = 1;        //所以仅能解引用a的第一个字节,赋予a的值也仅仅是改变了a地址中的第一个字节中的2个16进制位。
  return 0;
}

      2.指针类型决定了指针一步可以走多远(也称为步长)(跳过几个字节是由指针类型决定的)

                 例如

//假设arr首元素地址为0X004ffC40
int main( )
{
   int arr[10]={0};
   int *p = arr ; //p为arr 首元素的地址
   char  *pc =arr;
   printf("%p",p);   //0X004FFC40
   printf("%p",p+1); //0X004FFC44
  //指针p的类型是整形(4个字节),加1应跳过4个字节,是的指针地址也应是加4
   printf("%p",pc);  //0X004FFC40
   printf("%p,pc+1); //0X004FFC41
  //指针pc的类型是字符(1个字节),加1应该跳过1个字节,指针的值加1
   return 0;
}


 

        

                   2. 野指针

  野指针出现的原因:

                1.指针未初始化 

                  例如

int main()
{
    int *p;  //指针未初始化,称指针 p 为野指针
    *p =20; 
   return 0;
}

               2.指针越界访问

                         例如

int main( )
{
  int arr [10] ={0};
  int *p = arr[10 ];    
//该处访问的是数组中第11的元素的地址,超出了数组(仅有10个元素)的范围,则称p位野指针,越界访问空间。
   *p=10;
  return 0;
}

            

          3.指针指向的空间已经释放

               例如

int test()
{
  int a = 20;
  return &a:  //a为局部变量 它的位置传到主函数main前已被释放,即存放地址已被释放
}
int main()
{
    int *p=test(); //指针p 指向的是a 的地址,其地址已被释放,故p为野指针
    *p=20;         
     return 0;
}

如何避免野指针的出现:

        1.不忘给指针初始化 (给不知道指针指向哪个位置的指针初始化为空指针 例如:int*p=NULL;  NULL为空指针写法。给已知指针初始化 例如 int a =10;

int *pa =&a)

      2.小心越界(c语言本身不会检查越界情况)

      3.将指针释放后设置为NULL

      4.使用之前检查有效性

              例如  if (p!=NULL)

                       *p=10;

            

                      3.  指针的运算

1.指针加减整数

    指针加一,则指针加上与指针类型相符的字节(如整形指针加一地址后加4,字符指针加以地址加1),减法类似。

2.指针减指针(要求两指针指向同一位置)

  指针减指针得到的是两指针之间的个数  例如 int a=&arr[9]-&arr[0] ,a会等于9

3.指针关系运算(即指针可进行比较)

   例如  &arr[9]>&arr[8]      原因:随着数组下标的增加,地址也会由低到高增加。

                     4.二级指针

二级指针:指针的指针(地址)

        例如

int main()
{
   int a = 0;
   int *pa = &a;    //该处的*表示的是pa是一个指针 int 为a的指针的类型;
   int* *ppa = &pa; //*ppa 中的*表示的是ppa为一个指针,int*为pa 的指针的类型;ppa 是pa 的指针(指针的指针)称为二级指针
   return 0;
}

解引用操作:

int main()
{   
   int a = 0;
   int *pa = &a;    //该处的*表示的是pa是一个指针 int 为a的指针的类型;
   int* *ppa = &pa; 
   return 0;
}


               //*ppa=pa         *pa=a
           //可以合写为**ppa=pa      (理解为* (*ppa)两次解引用)

              一般情况下推荐分开写。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值