• 指针的用法


    指针是一块内存地址的首地址,这其中包含两个概念:
    1.指针是内存地址;
    2.指针还包括内存大小,void指针占用一个指针大小。
    比如:int *a指的是内存地址a,大小为int的内存块。

    不同类型的指针之间的联系和区别

    1.普通指针和数组指针

    #include
    int main()
    {
    	char a[4];
    	char (*pa)[4],*pb;
    	pa=&a;
    	pb=&a[0];
    	printf("pa占用内存大小是:%d\n",sizeof(*pa));
    	printf("pb占用内存大小是:%d\n",sizeof(*pb));
    	printf("pa是:%p\n",pa);
    	printf("pa+1是:%p\n",pa+1);
    	printf("pb是:%p\n",pb);
    	printf("pb+1是:%p\n",pb+1);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    pa占用内存大小是:4
    pb占用内存大小是:1
    pa是:0x7ff7b425df18
    pa+1是:0x7ff7b425df1c
    pb是:0x7ff7b425df18
    pb+1是:0x7ff7b425df19
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在上面的案例中,&a和&a[0]都表示char型数组a的首地址,但是他们的类型并不相同。
    &a[0],a先和[0]结合,所以&a[0]是一个元素的大小,在这里是1字节;
    &a,本质上是char *(&a)[4],是数组指针,此时&a表示的是char *[4]类型指针,是4字节;
    根据开头的原理,指针是内存块,指针的值是内存块的首地址,指针的类型是内存大小。
    因此,指针的递增(+1)指的是类型大小的递增。
    指针数组和数组指针的概念参考:c语言进阶笔记

    2.不同指针间的类型转换
    不同类型指针的强制转换会造成内存变化,但首地址不会变。

    int main()
    {
    	int a=12345678;
    	int *pa=&a;
    	char *pb=(char *)&a;
    	printf("pa:%p\n",pa);
    	printf("pa_value:%d\n",*pa);
    	printf("pb:%p\n",pb);
    	printf("pb_value:%d\n",*pb);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    pa:0x7ff7b0ebaf18
    pa_value:12345678
    pb:0x7ff7b0ebaf18
    pb_value:78
    
    • 1
    • 2
    • 3
    • 4

    同时可以发现,这个内存模型是大端对齐。

    指针与字符串

    通过指针定义的字符串形式如下:

    char *str="hello";
    
    • 1

    此时str具有只读属性,不能被修改:

    #include
    int main()
    {
    	char *a="hello";
    	*(a+1)='B';
    	printf("%s\n",a);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    此时编译会成功,但执行会崩溃,因为通过指针定义的字符串在内存中具有只读属性。
    如果指针指向的字符串不具有只读属性,那么就可以对其进行修改:

    #include
    int main()
    {
    	char a[20]="abc";
    	char *p;
    	p=a;
    	*(p+1)='2';
    	printf("%s\n",p);
    
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    爱上开源之golang入门至实战-第二章语言基础-内存管理
    微服务 & 云原生:搭建 K8S 集群
    C语言实现快速排序算法
    勤奋,专注,控制自己
    java中子类重写继承的方法的规则是什么?
    PBI 访问情况
    多目标应用:基于非支配排序粒子群优化算法NSPSO求解无人机三维路径规划(MATLAB代码)
    热门Java开发工具IDEA入门指南——创建新的Java应用程序(上)
    【JVM】JVM的内存区域划分
    程序员日常|为什么我在开发工作中偏爱这款键盘?
  • 原文地址:https://blog.csdn.net/weixin_39759247/article/details/126138794