C语言学习--指针
指针的的定义:
- 使用指针的需求 将某地址保存下来
- 指针使用的场景 传递与偏移
就是保存地址和传递参数
指针变量 int 型只能对应 int 变量(啥型号对应啥)
指针变量用来保存地址 取变量地址
指针的定义格式如下
基本这样传递就可以了,然后*取值
关于 * 和 & 的一些疑问?
如果已经执行了
pointer_1=&a ,给地址了
那么 &* pointer_1的含义是什么?
& 与 * 的优先级相同,但要按照从右往左的顺序
首先* pointer_1取值 ,相当于* &a
取出来变量a的值(5),所以后面 & a(5)
&* pointer_1 等价与 &a 都是 取地址
那么 *& a的含义是什么?
首先&a 取出地址 ,也就是 pointer_1一样
在进行 *取值运算,取出来变量a(5)
*&a 与 a 等价, 都是 取值
- 总结:
*
取值(解引用)&
取地址 (引用)
对于数组指针
比如
这种情况
这时候单指针指的是数组的起始位置 就是a[0]
如何想打印的话,使用循环
注意要保证二边类型一样:a[]数组 p=a a也是数组的初始位置
如果&a 就是取a数组的初始地址a[1] ,再取一次地址
所以不能用 p=&a
指针自增自减
以前已经见过i++ 和 ++i 等
那么要是 *p++ ,*p-- *++p 这些呢
试着说出 a[0] *p 和 j 的值
解答:先是(*p) 访问到2数组起始的空间
整体 j (*p)++变化 指向下一个空间 值,即数字取值3的空间
这时候数组初始位置 地址不变,这里面的值变为3
所以 a[0] 为3 *p整体变下来为3
这时候 说下j 的值 ,先看 如果 j=i++ ; i=1;结束后j等于几?
作者:顺其自然的活着1、首先,单独拿出来说++i和i++,意思都是一样的,就是i=i+1。
2、如果当做运算符来说,就是a=i++或者a=++i这样的形式。情况就不一样了。
先说a=i++,这个运算的意思是先把i的值赋予a,然后在执行i=i+1;
而a=++i,这个的意思是先执行i=i+1,然后在把i的值赋予a;
举个例子来说,如果一开始i=4。
那么执行a=i++这条语句之后,a=4,i=5;
那么执行a=++i这条语句之后,i=5,a=5;
同理,i--和--i的用法也是一样的。
链接:https://www.zhihu.com/question/19811087/answer/207494860
就是单独拉出来就是+1,做运算符 得化
j=i++; 先进行赋值, j=1; 再i++=2; i=2;
j=++i; 先i+1 ;i=2;再进行 赋值, j=2;
所以上面代码的j值
(*p)++ 取值3 地址数组初始位置
但是j= 先赋值 j=(*P)= 刚开始就赋值,所以为 *p =2
后面再运算 ++
*p才是3
带着把数组a[0]地址的值换了
指针与一维数组
比如这种 函数调用就是
d[] 其实与 *d 一样 都是i指针数组
但是没做这种d[] 这种,所以函数的形参里面应该不能放 数组
放个指针变量就行
void change (char *d)
拿不到数组长度
这种都可以改变值
d[1]就是 c[1]传给函数的
直接把c的地址传给函数形参指针d
等于d=c,地址相同
动态内存申请malloc
申请5*sizeof(int)=20字节
数组一开始定义好就确定下来了,数据是放在栈空间
进程地址空间:堆 栈
解释:栈空间的大小在编译时是确定的。如果使用的空间大小不确定,那么就要使用堆空间。
总申请代码:
申请100个字节放 "malloc success" ,如图:
但是还要free 释放内存
这里记录下指针p偏移错误
这里p++只想打印后面的 alloc success 但是这样free(p)会报错
可以在写一个 *p1
最后
free(p) ; p=NULL ;
释放操作
释放后,这时候p是野指针,就没有指向的
所以要 p=NULL;
如果不把p值为NULL,被称为野指针
注意:堆空间不会随子函数的结束而释放,必须自己free
栈空间与堆空间差异
栈空间:
看一个例子:
函数里面的正常打印,下面main函数里面的却不能正常打印
原因是上面是栈(自动分配空间) 函数结束后会自动释放
打印出来不正常
因为puts(p)这时候占用了栈空间
堆空间:
这是因为:申请堆空间不会因为函数结束结束,除非free否则一直能用
来做个例子吧:
输入一个整型数,然后申请对应大小空间内存,然后读取一个字符串,字符串的输入长度小于最初输入的整型数大小,最后输出输入的字符串即可(无需考虑输入的字符串过长,超过了内存大小);
主要讲下这里 char c; scanf("%c",&c);’
puts和 gets用的都是缓冲区
因为前面有scanf("%d",i) ,scanf在缓冲区里里面输入一个 数字
比如 10\n \n是结束符
此时缓冲区为
scanf读取后 \n还在缓冲区里面
所以 char c; scanf("%c",&c); 是为了去除缓冲区里面的\n
字符指针与字符数组的初始化
内存是有权限的: r(可读) ,w(可写), rw
这时候p[0]的地址里面内存不可写
字符串 常量存在 数据区,不是堆也不是栈,需要内存申请读写
char c[10] =“hello world”
把字符串变量 hello world 从数据区拿出来到栈
所以是可读可写的
这样 c[0]可以从 数据区拿'H'
而指针p[0]:
p[0]='H'; //不可以对常量区数据进行修改
这时候‘H’,在数据区,不能读取变量,也不能取起始地址,
再来看
p="world";//将字符串world的地址赋给p
”world“ 是字符串型 数据区 起始地址有
这样可以把它的起始地址赋给p
//c="world";//非法
c是数组,里面的地址不会更改,不能直接赋值
二级指针
-
二级指针只服务于一级指针的传递与偏移
-
要想在子函数中改变一个变量的值,必须把该变量的地址传进去
-
要想在子函数中改变一个指针变量的值,必须把该指针变量的地址传进去
类似这样,二级指针就是 p是一个指针, **p2=&p ;把p的原来的地址取过来
__EOF__

本文链接:https://www.cnblogs.com/halfup/p/15791310.html
关于博主:编程小萌新一名,希望从今天开始慢慢提高,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」