初阶指针C

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰指针是什么

🐰指针和指针类型

🌸指针+-整数

🌸指针的解引用

🐰野指针

🌸野指针的成因

🌸如何规避野指针

🐰指针运算

🌸指针+-整数

🌸指针-指针

🌸指针的关系运算

🐰指针和数组

🐰二级指针

🐰指针数组


🐰指针是什么

1.指针是内存中一个最小单元的编号,也就是地址

2.平时口语上所说的指针,通常指的是指针变量,是用来存放地址的变量

3.把内存划分为一个个的内存单元,这个内存单元大小是1字节,从概念上讲:编号 == 地址 == 指针

指针变量:

我们可以通过& (取地址操作符) 取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量

int main
{
    int a=10;//a是整形,占用4个字节的内存空间,没个字节都有对应的空间
    int* pa=&a;//&a  得到的是a的地址(指针),其实得到的是a所占内存中4字节中第一个字节的地址;pa是指针变量
}

‼️注:指针变量是用来存放地址的,存在指针中的值都会被当作地址,(锤子的眼里都是钉子)

🐰指针和指针类型

指针的类型为一个类型名和字符“ * ” 的组合,我们平时说“一个int 类型的指针”,其实是在说“一个类型为 int*的指针”。编译器认为这样的一个指针指向的内存单元为4 字节,并将其内容解释为 int 类型的值。

指针的类型有很多种,但指针类型大小是相同的:

    printf("%lu\n",sizeof(int*));
    printf("%lu\n",sizeof(char*));
    printf("%lu\n",sizeof(double*));
    printf("%lu\n",sizeof(short*));
他们所打印的值都是,都是8

‼️注:不同类型的指针大小相同,x86环境下大小是8,x64环境下大小是4

🌸指针+-整数

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

其运行结果为:

0x7ffeefbff3e8

0x7ffeefbff3ec

0x7ffeefbff3e9

&a:     0x7ffeefbff3e8
pa+1    0x7ffeefbff3ec
ppc+1   0x7ffeefbff3e9
可以看出来pa+1移动了4个内存单元即4个字节,而pc+1移动了1个内存单元即一个字节,因为pa是int类型的指针变量,所以需要移动1*sizeof(int),pc是char类型的指针变量,所以需要移动1*sizeof(char).

总结:指针类型决定了,指针进行+1,-1的时候,一步走多远

🌸指针的解引用

#include<stdio.h>
int main(){
int a=1000,b=1000;;
int* pa=&a;
    *pa=20;
char* pb=&b;
    *pb=20;
printf("a=%d b=%d\n",a,b);
}

其运行结果为:

a=20 b=788

大家就会奇怪,明明*pa=20,*pb=20一样,为什么a,b的值不一样呢?分析如下

int a=1000,b=1000;;
int* pa=&a;
    *pa=20;
char* pb=&b;
    *pb=20;
因为pa是整形的指针变量,可以访问4个字节的存储空间,刚好a也是整形变量,pa可以访问a中的所有值,而pb是字符型的指针变量,可以访问1个字节的存储空间,而b是整形变量,pb只能访问b中一个字节的内容

总结:指针类型就决定了,在解引用指针的时候能访问几个字节

🐰野指针

🌸野指针的成因

定义:野指针就是指针指向的位置是不可知的(随机的、不准确的、没有明确限制的)

(1)指针未初始化

int*p;未初始化

(2)当指针指向的范围超出数组arr的范围时,p就是野指针

int arr[10]={0};
int* p=arr;
*(p+10)=1;*(p+10)就是arr[10],这已经越界了

(3)指针指向空间释放

就是指针p之前指向的是一个有效的内存空间,现在那个空间被销毁了,这个指针p也就成为了野指针(这就好比张三以前有个女朋友,但是现在分手了,张三就成为了单身汪,因此单身汪是不能联系前女友的

(4)避免返回局部变量的地址

int* fun(int arr[]){
    int* p=arr;
    return str
}
int main(){
    int arr[10]={0};
    int* parr=fun(arr);这里返回的地址,已经在函数调用完成时销毁了
}

(5)指针的使用之前检查有效性

‼️注:一个指针不知道指向哪里时,暂时可以初始化NULL

🌸如何规避野指针

注意造成野指针的成因,就可以有效避免野指针的形成。

‼️注:一个指针不知道指向哪里时,暂时可以初始化NULL

🐰指针运算

🌸指针+-整数

#include<stdio.h>
int my_strlen(char* str)
{
    int count=0;
    while(*str!='\0')
    {
        count++;
        str++;//指针加减整数
    }
    return count;
}
int main()
{
    int len=my_strlen("abcdef");
    printf("%d\n",len);
    return 0;
}

🌸指针-指针(地址-地址)

指针-指针的条件:

(1)指针都是指向同一块区间的

(2)指针的类型是一致的

指针减指针是指针之间元素的个数(指针加整数等于指针,指针减指针等于整数)

strlen的模拟实现

#include<stdio.h>
int my_strlen(char* str)
{
    char* start=str;
    while(*str!='\0')
    {
        str++;//指针加减整数
    }
    return str-start;
}
int main()
{
    int len=my_strlen("abcdef");
    printf("%d\n",len);
    return 0;
}

🌸指针的关系运算

允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

例如:可以和p3的位置进行比较,不能和p2比较

🐰指针和数组

指针就是指针,不是数组,数组就是数组,也不是指针

指针的大小:4/8字节,指针式存放地址的,地址需要多大空间,指针变量的大小就是多少

数组大小:取决数组的元素的个数和元素的类型

🐰二级指针

​​​​​​​二级​​​​​​​指针是指向一级指针,一级指针的值是变量的地址,二级指针的值是一级指针的地址

#include<stdio.h>
int main()
{
    int a=10;//a在内存空间申请4个字节
    //一级指针
    int* pa=&a;//0x0012ff40,pa是指针变量,用来存放a地址,也得向内存申请4/8字节
    //二级指针
    int** ppa=&pa;//0x0012ff48,ppa是指针变量,用来存放pa地址,也得向内存申请4/8字节
    return 0;
}

🐰指针数组

指针数组是存放指针的数组

#include<stdio.h>
int main()
{
    int a=1;
    int b=2;
    int c=3;
    int* arr[]={&a,&b,&c};//arr就是指针数组,分别a,b,c的地址给arr[0],arr[1],arr[2]
    for(int i=0;i<3;i++)
    {
        printf("%d ",*arr[i]);
    }
    return 0;
}

用指针数组模拟二维数组

#include<stdio.h>
int main()
{
    int a[]={1,2,3};
    int b[]={3,4,5};
    int c[]={5,6,7};
    int* arr[]={a,b,c};
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            printf("%d",arr[i][j]);//模拟二维数组,和二位数组还是有差距
            //printf("%d",*(*(arr+i)+j));
        }
        printf("\n");
    }
    return 0;
}

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

  • 47
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 38
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值