当前位置: 首页 > news >正文

中国大学MOOC-C语言第九周指针(上)

         本文为个人总结,难免出现错误,恳请批评指正。

        PS:编译环境:Dev-C++        编译器:gcc

9.1-1取地址运算:&运算符取得变量的地址

              一、 &取址操作的时候操作数必须是变量;&不能对没有地址的东西取地址。C语言的变量放在内存中。

                &可以取出一个变量的地址这个地址的大小、数据类型和  int是否相同取决于编译器,取决于计算机架构(32位 or  64位)。

                二、&不能取的地址:没有地址的东西取地址,人话就是&右边必须是变量

报错代码一:8字节指针强行转换为int4字节,编译过不了

#include<stdio.h>int main()
{int i=0;int p;p = (int)&i;printf("0x%x\n", p);return 0;
}

报错代码二:原因语法问题

#include<stdio.h>int main()
{int i=0;int p;
//	p = (int)&i;p = (int)&(i++);p = (int)&(i+p);printf("0x%x\n", p);return 0;
}

        PS:本地变量i,p分配在内存堆栈,自顶向下分配内存,先定义的变量地址高,后定义的变量地址低。(注意计算机是多少位架构)

       

接下来我们来看数组的地址数组单元的地址相邻的数组单元的地址.

        由上图容易看出:对于同一个数组的地址打印,&a==a==&a[0].

9.1-2指针:指针变量就是记录地址的变量

                一、重新认识scanf

                scanf函数中一定有一个方法可以接收变量地址。

                指针就是保存地址的变量。

#include<stdio.h>
int main()
{
//	指针就是保存地址的变量int i;int* p= &i;int* p,q;int *p,q; return 0;}

        上图中下面两行里面只有 p 是指针变量,q只是普通的int整型变量,在C语言中没有int *这种类型,注意区分,在自己写代码的时候也要注意。

        指针变量的值是内存的地址,普通变量的值是实际的值,指针变量的值是具体实际值的变量的地址。(有点绕口哈哈哈,但是概念确实是这样的)

        二、作为参数的指针        

        由上图可知可以利用函数传递地址。

        在函数中我们讲参数的转移是值的传递,但是现在传进来的是地址,所以通过地址在函数内部可以访问到i这个本地变量,可以修改 i 这个本地变量,示例代码如下:

#include<stdio.h>
void f(int *p);
int main()
{int i=6;printf("&i=%p\n",&i);f(&i);
//	g(i);printf("i=%d",i);return 0;	
}
void f(int *p)
{printf("p=%p\n",p);printf("*p=%d\n",*p);*p=26;
}

        

        作为参数的指针可以访问到对应内存地址中的变量;指针的运算符&*,涉及到指针的时候从右往左看只看字符举例如下:

互相反作用:*&yptr  ->  *(&yptr)  ->  *(yptr的地址) -> 得到那个地址上的变量 ->yptr

                       &*yptr -> &(*yptr) ->&y -> 得到y的地址即yptr的地址                 ->yptr

                注意左值是什么意思:是因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果,比如a[0]=2;*p=3.   是特殊的值所以叫左值

9.1-3指针的使用:指针有什么用呢

               一、指针第一个应用场景:作为函数中的参数交换数值

#include<stdio.h>
void swap(int *pa,int *pb);
int main()
{int a=5;int b=6;swap(&a,&b);printf("%d %d",a,b);return 0;	
}
void swap(int *pa,int *pb)
{int t=*pa;*pa=*pb;*pb=t;
}

                二、指针第二个应用场景:函数返回多个值,某些值需要通过指针返回,传入的参数实际是需要保存带回的变量;(代码太长我懒得敲了,截的图凑合看吧)

        指针应用场景2b:函数返回运算的状态结果(实际的值)通过指针返回。常用套路是让函数返回特殊的不属于有效范围内的值来表示出错:

                    -1或0(文件操作的时候会看到大量的例子)

                但是当任何数值都是有效的可能结果时候,就得分开返回了,后续语言(C++,Java)采用异常机制来解决这个问题。

               

       

        三、指针最常见的错误:定义了指针变量直接用:翻译过来就是实际内存中还没有这个变量的位置,编译是一定过不了的。

        任何一个指针变量没有被赋值之前,没有得到任何一个实际变量的地址之前,不能通过它访问其他变量。

9.1-4指针与数组:为什么数组传进函数后的sizeof就不对了

                数组变量是特殊的指针,在参数表中出现,以下四种函数原型是等价的:

        int sum(int *ar, int n);

        int sum(int *, int);

        int sum(int ar[], int n);

        int sum(int [], int);

           函数参数表里的数组实际上是指针(sizeof(a) == sizeof (int*)),下面两个等价函数

void  minmax(int a[], int len, int *max, int *min)

void  minmax(int *a, int len, int *max, int *min)

[] 运算符可以对数组做,也可以对指针做;

*运算符可以对指针做,也可以对数组做

数组变量是const的指针,所以不能被赋值。

int a[]   <==>  int *   const a=......

9.1-5指针与const:指针:指针本身和所指的变量都可能const

        一、指针与const        

        指针是const:表示一旦得到了某个变量的地址,不能再指向其他变量。

举例:int* const q=&i;  //q是const,q只能指向i了,不能指向别人了

*q=26; // 可以写

q++;//ERROR!

        指针所指是const:表示不能通过这个指针去修改那个变量(并不能使那个变量成为const)

const  int* p=&i;

*p=26;  //ERROR!   原因是(*p)是const类型

i=26;//OK

q=&j;//OK

下面这几种写法的含义:

int i;

const  int*  p1 = &i;          变量p1是const,不能被修改

int const*  p2=&i;             变量p2是const,不能被修改

int *const  p3=&i;        指针是const,指针不能被修改

判断哪个被const了的标志是const在前面还是后面

二、转换

        

三、const数组

        数组实质上已经是const了:int a[]   <==>  int *   const a=......

http://www.lryc.cn/news/627066.html

相关文章:

  • 360报毒HEUR/QVM03.0.7EBB.Malware.Gen问题
  • lock4j 库中的 @Lock4j 注解进行全面的概述和深度的源码级剖析。
  • Ubuntu实现程序开机自动运行
  • Windows 如何清理右键菜单?电脑桌面右键菜单里出现一个清理内存 怎么去掉?
  • 强制重启导致Ubuntu24.04LTS amd的WIFI无法使用的解决方案
  • 电芯自动分选装盒机:高效整合分选与包装的智能化解决方案
  • unfold 切图像,图形transformer的切割操作
  • 【蒸蒸日上】军八武将篇——标1
  • 仿真驱动的AI自动驾驶汽车安全设计与测试
  • 30.Linux cobbler自动化部署
  • 计算机网络基础复习
  • 对象存储 COS 端到端质量系列——终端 COS SDK 网络优化
  • 【自记】Power BI 中 ALL、ALLSELECTED、ALLEXCEPT、ALLNOBLANKROW 的区别说明
  • Python打卡Day47 注意力热图可视化
  • 分享一个基于spark大数据的海洋塑料污染监测与可视化分析系统 基于Python的海洋塑料污染数据交互式可视化分析系统
  • Qwen Image edit的ComfyUI工作流搭建
  • 2025招商铸盾车联网CTF竞赛初赛题解
  • IT运维背锅权限泄露?集中式管控如何化解风险?
  • Docker Compose命令一览(Docker Compose指令、docker-compose命令)
  • Javascript面试题及详细答案150道之(121-135)
  • Linux Capability 解析
  • 达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
  • Java 通过 m3u8 链接下载所有 ts 视频切片并合并转换为 mp4 格式
  • 齐次线性方程组最小二乘解
  • 接美国血统(中序、后序→前序)
  • 【网络运维】Linux:正则表达式
  • 虚幻引擎目录结构
  • AGV小车cad+三维图+设计说明书
  • C++ 力扣 438.找到字符串中所有字母异位词 题解 优选算法 滑动窗口 每日一题
  • Java 线程池ThreadPoolExecutor源码解读