指针超级无敌大详解

目录

一.初始指针

1.引入 关于内存和地址

2.各指针变量基本含义

3.野指针

4.⼆级指针

①含义

二.指针的使用

1.指针的运算

①指针+-整数

②指针-指针

③指针的关系运算

2. 使⽤指针访问数组

①数组名的理解

②具体代码

3.指针传参

三. 关于指针较复杂的运用

1.指针数组

2.函数指针


一.初始指针

1.引入 关于内存和地址

我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数 据也会放回内存中,那这些内存空间如何⾼ 效的管理呢? 其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。

1byte = 8bit

1KB = 1024byte

1MB = 1024KB

1GB = 1024MB

1TB = 1024GB

1PB = 1024TB

其中,每个内存单元,相当于⼀个学⽣宿舍,⼀ 个⼈字节空间⾥⾯能放8个⽐特位,就好⽐同学们 住的⼋⼈间,每个⼈是⼀个⽐特位。 每个内存单元也都有⼀个编号(这个编号就相当 于宿舍房间的⻔牌号),有了这个内存单元的编 号,CPU就可以快速找到⼀个内存空间。

在计算机中我们把内存单元的编号称为地址,C语⾔中给地址起 了新的名字叫:指针

2.各指针变量基本含义

理解指针,首先要了解取地址操作符(&)

 #include <stdio.h>
 int main()
{
     int a = 10;
     printf("%p\n", &a);//%p打印出&a取出的地址,即a的地址
     return 0;
}

而这样的地址值存放在哪⾥呢?答案是:指针变量中。

#include <stdio.h>
 int main()
 {
     int a = 10;
     int* pa = &a;//取出a的地址并存储到指针变量pa中

 //这⾥pa左边写的是int* ,*是在说明pa是指针变量,⽽前⾯的int 是在说明pa指向的是整型(int)类型的对象

     return 0;
 }

要通过指针找到其指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)

#include <stdio.h>
 int main()
 {
     int a = 100;
     int* pa = &a;
     *pa = 0;    //a的值变为0
     return 0;
 }

类型

①整形指针 int *p

②字符指针 char *p

③数组指针变量 

 int arr[10] = {0};
 &arr;//得到的就是数组的地址
 //如果要存放个数组的地址,就得存放在数组指针变量中,如下:
 int(*p)[10] = &arr

④函数指针

函数名就是函数的地址

函数指针变量的使用 

 #include <stdio.h>
 int Add(int x, int y)
 {
     return x+y;
 }
 int main()
 {
     int(*pf)(int, int) = Add;
     printf("%d\n", (*pf)(2, 3));
     printf("%d\n", pf(3, 5));
     return 0;
}

 输出结果:

5

8

3.野指针

成因

1.指针未初始化

2.指针越界访问

3. 指针指向的空间释放

#include <stdio.h>
 int* test()
 {
     int n = 100;
     return &n;
 }
//离开函数text,n的空间被释放了
 int main()
 {
     int*p = test();
     printf("%d\n", *p);
     return 0;
 }

4.⼆级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪⾥?

①含义

指向指针的地址,对其解引用得到指针指向的变量的地址

#include<include.h>
int main()
{
    int a=0;
    int *pa=&a;
    int **ppa=&pa;

    return 0;
}

二.指针的使用

1.指针的运算

①指针+-整数

(1)

#include <stdio.h>
 int main()
 {
     int n = 10;
     char *pc = (char*)&n;
     int *pi = &n;
     printf("%p\n", &n);
     printf("%p\n", pc);
     printf("%p\n", pc+1);
     printf("%p\n", pi);
     printf("%p\n", pi+1);
     return  0;
 }

 运行之后可以看出, char* 类型的指针变量+1跳过1个字节,int* 类型的指针变量+1跳过了4个字节, 这就是指针变量的类型差异带来的变化。

(2)

#include <stdio.h>
int main()
 {
     int arr[10] = {1,2,3,4,5,6,7,8,9,10};
     int *p = &arr[0];
     int i = 0;
     int sz = sizeof(arr)/sizeof(arr[0]);
     for(i=0; i<sz; i++)
     {
            printf("%d ", *(p+i));//p+i 
     }
     return 0;
 }
 

 因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸⽠就能找到后⾯的所有元素。

②指针-指针

 #include <stdio.h>
 int my_strlen(char *s)
 {
     char *p = s;
     while(*p != '\0' )
     p++;
     return p-s;  //得出两指针之间的元素数
 }
 int main()
 {
     printf("%d\n", my_strlen("abc"));
     return 0;
}

只有在同一区域同类型的指针可以做差

③指针的关系运算

指针可以比较大小

2. 使⽤指针访问数组

①数组名的理解

一般表示表示数组首元素的地址

当出现&arr或者sizeof(arr)时,才表示为整个数组

并且arr与&arr的地址值相同,不过二者类型不同

②具体代码

 #include <stdio.h>
 int main()
 {
    int arr[10] = {0};
    int* p = arr;
    for(i=0; i<sz; i++)
      {
             scanf("%d", p+i); //或者这样 scanf("%d", arr+i);
 
        }
 
    for(i=0; i<sz; i++)
     {
         printf("%d ", *(p+i));//或者这样 printf("%d ", p[i]);
     }
    return 0;
 }

3.指针传参

void test(int arr[])//参数写成数组形式,本质上还是指针
 {
     printf("%d\n", sizeof(arr));
 }
 void test(int* arr)//参数写成指针形式
{
 printf("%d\n", sizeof(arr));//计算⼀个指针变量的⼤⼩ 
}
 int main()
 {
     int arr[10] = {1,2,3,4,5,6,7,8,9,10};
     test(arr);
     return 0;
 }

总结:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

三. 关于指针较复杂的运用

1.指针数组

指针数组的每个元素都是⽤来存放地址(指针)的, 指针数组的每个元素是地址,⼜可以指向⼀块区域。

指针数组的使用类似于二维数组 

#include <stdio.h>
 int main()
 {
     int arr1[] = {1,2,3,4,5};
     int arr2[] = {2,3,4,5,6};
     int arr3[] = {3,4,5,6,7};
 //数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
 
     int* parr[3] = {arr1, arr2, arr3};
     int i = 0;
     int j = 0;
     for(i=0; i<3; i++)
     {
         for(j=0; j<5; j++)
         {
             printf("%d ", parr[i][j]);
         }
         printf("\n");
     }
     return 0;
 }

2.函数指针

函数指针变量的使用:通过函数指针调⽤指针指向的函数。

#include <stdio.h>
 int Add(int x, int y)
 {
     return x+y;
 }
 int main()
 {
     int(*pf3)(int, int) = Add;
     printf("%d\n", (*pf3)(2, 3));
     printf("%d\n", pf3(3, 5));
     return 0;
}

输出结果:

5

8

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值