C语言之指针

本文深入解析指针概念,探讨其在变量地址存储、内存申请与释放、字符串逆序算法实现等方面的应用,同时对比指针与数组的区别,解析野指针问题,以及在不同场景下指针的正确使用方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 指针的概念
    (1) 指针也是一种变量,用来存放其他变量地址的变量,指针的地址也是最开头的地址
    (2) int a = 0
    int *p = &a (int * 是一种数据类型,所以p 用来存放地址)
    *p = 100 等价于 a = 100(因为p指向a)
    注意:系统通过变量名或者地址来访问内存
    (3)*有两个含义:定义时表示后面的变量是指针;使用时表示取值
    (4)无论什么类型的指针都是四个字节
    在这里插入图片描述
    运行结果:4 4 4 4
    (5)指针只能指向同类型的变量 :char b = ‘a’
    int *p = &b × char *p = &b √
    在这里插入图片描述
    上面这个值得注意:int *p1 = &a ,一个是整型,一个数组型(&a),不兼容,需要加强制转换符(int *)&a

  2. 地址传递
    在这里插入图片描述
    运行结果 :a = 1 b = 2
    a和b的值并没有交换,因为函数调用是是在栈空间里面交换a和b的值,交换完释放空间,原函数值不变
    只能进行地址传递,用指针来交换值,才能真正的交换,因为指针指向原函数空间

    在这里插入图片描述
    运行结果: a = 2 b = 1
    注意:程序中的交换函数用了一个小算法 ,记住

  3. 指针运算
    (1)对于本题先看第一种 不定义y = 0
    在这里插入图片描述
    运行结果:在这里插入图片描述

再看第二种定义y = 0的运行结果:在这里插入图片描述

为什么呢?
首先第二个printf把px指向的值加一 也就是px = 4
再看第三个printf 中 ** px++表示输出
px 后把px加一 也就是px指向的地址加一*
最后在第四个printf中,第二种定义了y=0,px的地址等于y的地址,所以输出0;但是如果未定义y=0,px地址加一不知道指向哪里去,所以指向的值也是乱码
在这里插入图片描述
(2)利用指针实现库函数strcpy
在这里插入图片描述
4. 指针的内存申请(野指针的问题)

char *str ; *str = ‘a’ ×
这是定义了一个野指针 指向了不能使用的内存,所以要想使用空指针就需要申请一个内存

char *str = (char *)malloc (sizeof (char) * 100)
申请了连续的100个字节的堆内存空间,并且返回这段内存的首地址给str(str在栈空间)
注意使用malloc需要调用头文件“stdlib.h”,另外用完之后需要释放内存free(str),如果不释放,就会内存泄漏

例如用指针实现字符串的逆序:
在这里插入图片描述
在这里插入图片描述
虽然算法不难,不过我要解释其中几行为什么要这么写
(1)第8行为什么要加个str ?
因为char *end是定义了一个指针,他指向地址,如果单纯写length - 1,肯定不对,因为length - 1是个整型数据,整型数据很明显不能给指针,而加上str就不一样了 str代表地址,地址可以移动,通过加减整数
(2)第22行为什么写个strcpy函数
因为strcpy函数是把变量赋值给str,这样就可以修改str中的值了,下面两种写法来逆序就是错的
char *str = “helloworld”;这种定义可以 ,但是因为字符串是常量,不能改变
char str[32] = “helloworld”;数组名相当于常指针,固定了地址,字符串常量也在内存中有个固定地址,二者不可改变
(3)为什么不在主函数里面完成各个程序,因为比如这个逆序操作,如果放在主函数里面会改变str里面的值,写调用函数的话不会修改。

面试题:
char str1[] = “abc”;
char str2[] = “abc”;
const char str3[] = “abc”;
const char str4[] = “abc”;
const char *str5 = “abc”;
const char *str6 = “abc”;
char *str7 = “abc”;
char *str8 = “abc”;
cout << ( str1 == str2 ) << endl;
cout << ( str3 == str4 ) << endl;
cout << ( str5 == str6 ) << endl;
cout << ( str7 == str8 ) << endl;
结果是:0 0 1 1
解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;
而str5,str6,str7,str8是指针,它们指向相同的常量区域

  1. 指针与数组
    (1)指针和数组可以相互表示输出
    在这里插入图片描述
    (2)数组和指针又有区别,数组可以赋值,但是野指针不能,因为野指针定位随机,里面盛放的值不确定,所以不能修改里面的值;数组名(包括字符串常量)是常指针,不能修改,因为是系统给分配的固定地址,但是野指针可以指向别的地址
    在这里插入图片描述
    思考题:
    在这里插入图片描述
    输出结果:
    在这里插入图片描述
    解释:比较难理解的是p2中的**(int)a+ 1** ,通过运行发现他代表数组第一个元素的第二个字节(一个整型元素是四个字节),他的值也当然是乱码

6.指针与字符串
在这里插入图片描述
运行结果:hello

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值