当前位置: 首页 > 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.xdnf.cn/news/1331101.html

相关文章:

  • 数据结构:利用旋转在AVL树中维持平衡(Inserting in AVL with Rotation)
  • 自建开发工具IDE(一)之拖找排版—仙盟创梦IDE
  • RabbitMQ 基础
  • 吱吱企业通讯软件保证内部通讯安全,搭建数字安全体系
  • Windows 中的“计数器”
  • TDengine IDMP 运维指南(数据导入导出)
  • 第三阶段数据-3:数据库脚本生成,备份与还原,分离与附加
  • RabbitMQ:SpringAMQP Topic Exchange(主题交换机)
  • Oracle:配置让插入语句时id自动输入
  • 生产环境MongoDB分片策略优化与故障排查实战经验分享
  • 翻译记忆库(TMX)与机器翻译的结合应用
  • ​​pytest+yaml+allure接口自动化测试框架
  • 计算机视觉(二)------OpenCV图像视频操作进阶:从原理到实战
  • MYSQL-增删查改CRUD
  • 遥感机器学习入门实战教程|Sklearn 案例④ :多分类器对比(SVM / RF / kNN / Logistic...)
  • 【C++】--指针与引用深入解析和对比
  • 2025 | 腾讯混元RLVMR颠覆强化学习:可验证推理奖励引爆AI智能体新范式!
  • 文本智能抽取:如何用NLP从海量文本中“炼“出真金?-告别无效阅读,让AI成为你的“信息炼金师
  • git 生成 Patch 和打 Patch
  • 在完全没有无线网络(Wi-Fi)和移动网络(蜂窝数据)的环境下,使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本2)
  • 汽车ECU实现数据安全存储(机密性保护)的一种方案
  • 网页作品惊艳亮相!这个浪浪山小妖怪网站太治愈了!
  • uni-app跨端开发最后一公里:详解应用上架各大应用商店全流程
  • 云计算学习100天-第26天
  • 《CDN加速的安全隐患与解决办法:如何构建更安全的网络加速体系》
  • 【Ansible】变量、机密、事实
  • Ubuntu-安装Epics Archiver Appliance教程
  • ansible playbook 实战案例roles | 实现基于firewalld添加端口
  • 如何使用matlab将目录下不同的excel表合并成一个表
  • 四川方言语音识别数据集,1500小时合规真人采集,高质量标注助力ASR与大模型训练