浅谈C语言指针

什么是指针?

  在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中的另一个地方的值。由于通过地址能找到所需的变量单位,可以说,地址指向该变量单元。因此,降低至形象化的称为“指针”。意思是通过它能找到以它位地址的内存单元。

图解指针:

在这里插入图片描述

代码解析

#include <stdio.h>int main()
{int a = 20;
//在内存中开辟一段空间int *p = &a;
//“&a”:将变量a的地址取出,使用“&”取地址操作符
//将a的地址存放在p变量中,p就是一个指针变量return 0;
}

总结

  指针就是变量,用来存放地址的变量。所以说,存放在指针中的值都会被当做地址来处理

为什么存在指针?

生活中例子

现实生活中我们管理土地的方式是:
国家→省→市→县(区)→街道→楼→房间
  这样做我们可以很好地将土地分区管理,然后通过一个地址就能找到对应的位置。可以方便有快捷的管理。

其实计算机中的内存管理也是采用了这样的思路:
  将计算机中的内存分成很多小单元,每个单元都对应一个独一无二的地址,这样就一个地址表示一块空间。

指针的运算

指针±整数

#include <stdio.h>int main()
{int a = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n);      //0x00FFF121printf("%p\n", pc);      //0x00FFF121printf("%p\n", pc+1);    //0x00FFF122printf("%p\n", pi);      //0x00FFF121printf("%p\n", pi+1);    //0x00FFF125return 0;
}

指针-指针

用模拟实现strlen解析

int my_strlen(char *s)
assert(s != NULL);
{char *p = s;while(*p = '\0')p++;return p-s;
}

总结

  指针的类型决定了指针向前或者向后走一步有多大,也就是说指针的类型决定了在对指针进行使用时的权限有多大(能操作几个字节)
  指针之间相加减是在计算两个指针之间相差多少元素,并且只能在同一块空间中进行。
在关系运算中,有以下标准规定:
  允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

二级指针

  指针变量也是变量,是变量就有地址,那么指针变量的地址存放在哪里?
  这就是二级指针!!!!

图解二级指针 在这里插入图片描述

  a的地址存放在pa中,pa的地址存放在ppa中。所以说pa是一级指针,而ppa是二级指针。通过对ppa中的地址解应用可以找到pa,所以*ppa访问的就是pa,再对pa进行解引用就可以找到a,也就是说:**ppa就是a

指针表达式解析

  当有代码

char ch = 'a';
char *cp = &ch;

  下面的代码那些可以做左值?那些可以做右值?

&ch;		//&ch是地址常量,不能做左值,只能做右值
cp;			//cp是变量,可以做左值,也可以做右值
&cp;		//&cp是地址常量,不能做左值,只能做右值
*cp+1;		//*cp+1表达式的结果是常量,不能做左值,但可以做右值
*(cp+1);	//*(cp+1)表示的是ch之后的一块空间,可以做左值,也可以做右值
++cp;		//++cp在c语言中变量的前置++不能作为左值,只可以作为右值,但在c++中变量的前置++可以作为左值
cp++;		//cp++在c语言中变量的后置++不能作为左值,只可以作为右值
*++cp;		//*++cp表示的是ch的下一块空间,可以做左值,也可以做右值
*cp++;		//*cp++中++是后置的,是先用*cp在做++,所以既可以做左值,也可以做右值
++*cp;		//++*cp表达式是对*cp的前置++,所以不能做左值,只能做右值
(*cp)++;	//(*cp)++表达式是对*cp的后置++,所以不能做左值,只能做右值
++*++cp;	//++*++cp是对ch的下一块空间的内容做的前置++,所以不能做左值,只能做右值
++*cp++;	//++*cp++是对ch的内容做前置++,同时也是对cp进行后置++,所以不能做左值,只能做右值

左值:强调的是空间/位置
右值:强调的是内容/结果

指针数组与数组指针

指针数组

  指针数组是一个存放指针的数组,例如:int arr[20],是一个类型为"int*"、名为“arr”、存放了20各元素的数组

数组指针

  数组指针是一个指针,我们知道整形指针“int *point”是一个能够指向整形数据的指针,当然数组指针“int (*p)[10]”就是一个能够指向数组的指针

代码解析
int (*p)[10];
//1、p先和*结合,说明p是一个指针变量,然后指向的是一个大小为10个整数的数组,所以平时一个指针,指向一个数组,叫做数组指针
//要注意的是,[]的优先级要高于*,所以必须要加上()来保证p先和*结合,否则p将先和[]结合成为“int* p[10] ”,这样就成了一个指针数组
数组指针的使用

先分析一下以下代码

int arr[10] = {0};
//arr: 表示数组首元素的地址
//&arr:表示数组的地址
//具体差异在哪里?
printf("%p\n", arr);//输出的是第一个元素的地址
printf("%p\n", arr+1);//输出的是第二个元素的地址
printf("%p\n", &arr+1);//输出的是整个之后的地址

  从这里我们可以看出产生的结果是截然不同的,虽然数组的地址和首元素的地址值是相同的,但是意义不相同。既然出现了数组的地址,就需要存储数组地址的容器,这时我们会考虑到用数组指针来存放数组的地址,由数组指针的定义得知,使用数组指针来存放数组的地址是再合适不过了。
  现在我们要将一个二维数组传参,我们应该怎么做?

void test()
{int arr[3][5] = {0};print(arr);//这里print函数的参数应该如何设计?
}
void print(int arr[3][5])
{}
//这样可以吗?当然可以!只是最原始的方式
void print(int arr[][5])//ok?
{}
//这样可以吗?当然可以!因为二维数组的行可以省略,列不可以省略
void print(int **arr)//ok?
{}
//这样可以吗?当然不可以!因为这是一个二级指针,二级指针存放的是一级指针的地址,而不是数组的地址
void print(int (*arr)[5])//ok?
{}
//这样可以吗?当然可以!这是一个典型的数组指针,用来存放数组的地址,所以可以作为print的参数

  通过上面的认识,来看一下下面的代码

int arr[10];//数组
int *parr1[10];//指针数组
int (*parr2)[10];//数组指针
int (*parr3[10])[10];//存放数组指针的数组
//parr3是名字先和[10]结合,说明这是一个拥有10个元素的数组,
//对于数组来说,去掉名字和[],其他的就是这个数组中存放的元素的类型,由(*)[]可知,这个数组中存放的是数组指针

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转:EXCEL数据有效性设置

原文&#xff1a; http://hi.baidu.com/guosq/blog/item/88b37cd5bd367cfda144dfa0.html 先看图&#xff0c;有学生成绩表格&#xff0c;录入要求&#xff1a; 1. 成绩范围&#xff1a; 0 - 100&#xff1b; 2. 课程&#xff1a;只能是语文、数学、英语。 操作步骤&#xff1a;…

科学家绘制果蝇完整大脑高清图—可借此追踪任何两个神经元之间的连接

研究人员利用电子显微镜重建了果蝇的一系列神经元。来源&#xff1a;中国科学报科学家近日首次对黑腹果蝇的整个大脑进行了足够详细的成像&#xff0c;从而能探测每个神经元之间的单独连接&#xff0c;或者说突触。由此获得的图像数据库可帮助研究人员描绘支撑果蝇嗅闻、嗡嗡叫…

浅谈野指针

什么是野指针&#xff1f; 野指针并不是NULL指针&#xff0c;它是一个指向“垃圾”内存的指针&#xff0c;也就是说指向的地址是随机的&#xff0c;无法得知他的地址&#xff0c;操作系统自动对其进行初始化。   在计算机中&#xff0c;内存的分配由操作系统来管理&#xff0…

转: Linux下单网卡多vlan多虚拟机

#启动xen服务&#xff1a;xend start#列出虚拟机xm list#startxm create -c 虚拟机名#进入虚拟机xm console 虚拟机名#退出虚拟机ctrl]#关闭xm shutdown linux bridge实现了ieee 802.1d协议&#xff0c;这个实现&#xff0c;不能支持VLAN的功能。也就是说&#xff0c;这个实现&…

谈谈 Android 有多成功!欧盟这么罚它

选自 | Stratechery 作者 | Ben Thompson 编译 | 网易智能 参与 | 乐邦西方知名科技博主本汤普森&#xff08;Ben Thompson&#xff09;近日发布题为“欧盟VS Android”的文章&#xff0c;称谷歌固然有其违法的地方&#xff0c;但欧盟剥夺谷歌从其冒着高风险斥资数十亿美元开发…

VSS 错误链接

VSS服务器没有开&#xff08;或者链接不上、共享断开等情况&#xff09;&#xff0c;vs工程打开会提示你找不到VSS数据库&#xff0c;不小心点错了位置&#xff0c;结果VS链接不上VSS了&#xff0c;老是提示如下错误&#xff1a;VSS出项错误"Could not find the Visual So…

算法的五大特性

输入&#xff08;Input&#xff09; 算法可以有0个或多个输入&#xff0c;用来说明对象的初始值&#xff0c;其中的0的输入的意思是指算法自己已经定出了初始条件 输出&#xff08;Output&#xff09; 算法中必须有1或多个输出&#xff0c;因为输出是用来说明数据处理后的结果…

《纽约时报》评中国技术热潮:追捧“上菜机器人”等无意义的新奇产品

来源&#xff1a;纽约时报编译&#xff1a;全球技术地图上海的机器人魔力餐厅里的非人类服务员只能做到这一步。在食客们拍完照片和视频后&#xff0c;常规的服务员会上前进行服务。上海——能读人想法的耳机什么都没读出来。检测火灾的机器人已被宣布为安全隐患。机器人服务员…

运算符的优先级(Operator Precedence)总结(表)

概念 在一个表达式中可能包含多个有不同运算符连接起来的、具有不同数据类型的数据对象&#xff1b;由于表达式有多种运算&#xff0c;不同的结合顺序可能得出不同结果甚至出现错误运算错误&#xff0c;因为当表达式中含多种运算时&#xff0c;必须按一定顺序进行结合&#xff…

队列 VS 堆栈

队列&#xff0c;又称为伫列&#xff08;英文queue&#xff09;&#xff0c;是先进先出&#xff08;FIFO, First-In-First-Out&#xff09;的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端&#xff08;称为rear&#xff09;进行插入操作&#xff0c;在前端&…

10家最具创新性的机器学习公司

来源&#xff1a;资本实验室摘要&#xff1a;机器学习是实现人工智能的一种方法&#xff0c;通过使用算法来解析数据、从中学习&#xff0c;然后对现实世界中的事件做出预测和判断。机器学习已经在各个行业得到广泛应用。近日《Analytics Insight》杂志评选出10家最具创新性的机…

静态数据成员与非静态数据成员

静态数据成员 用static来声明静态成员&#xff0c;它是类的一部分&#xff0c;有该类中的所有对象共同使用和维护&#xff0c;实现类中数据的共享&#xff08;静态区&#xff09;&#xff0c;要受private控制符影响。 非静态数据成员 类的每个实例都有一份拷贝(动态区)。 从内…

【译】微型ORM:PetaPoco

PetaPoco是一款适用于.Net 和Mono的微小、快速、单文件的微型ORM。 PetaPoco有以下特色&#xff1a; 微小&#xff0c;没有依赖项……单个的C#文件可以方便的添加到任何项目中。工作于严格的没有装饰的Poco类&#xff0c;和几乎全部加了特性的Poco类Insert/Delete/Update/Save …

李飞飞公布谷歌云TPU、AutoML、行业方案等多项进展,AI云计算成谷歌全新增长点...

来源&#xff1a;全球人工智能摘要&#xff1a;7 月 24 日-26 日&#xff0c;Google Cloud NEXT 18 大会在美国旧金山举行。7 月 24 日-26 日&#xff0c;Google Cloud NEXT 18 大会在美国旧金山举行&#xff0c;Google Cloud作为谷歌人工智能未来业务发展的基础性平台&#xf…

new/delete和malloc/free的区别

malloc/free和new/delete的区别 共同点 都是从堆上申请空间&#xff0c;并且需要用户手动释放。 不同点 1、malloc/free是函数&#xff0c;new/delete是操作符。 2、malloc需要用户区手动计算空间的大小&#xff0c;new直接再后面跟上空间的类型就好。 3、malloc返回的是…

this的用法添加样式给tr或者div

onmouseover与onmouseout事件处理器&#xff0c;分别对应为鼠标移上去和鼠标移开时触发。οnmοuseοver"this.classNamemenu_title2;" 是鼠标移到该单元格上去时应用的css样式为“.menu_title2”的样式 οnmοuseοut"this.classNamemenu_title;"是鼠标离…

C语言中生成可执行程序的过程

预处理&#xff1a;展开头文件/进行宏替换/去掉注释/条件编译 编译&#xff1a;检查语法是否有错误&#xff0c;生成汇编代码 汇编&#xff1a;将汇编代码转换可供机器识别的机器码 链接&#xff1a;将多个文件链接到一起生成可执行程序

Gartner:2018年十大科技趋势与其对IT和执行的影响

来源&#xff1a;云技术实践摘要&#xff1a;Gartner每年发布的十大战略科技趋势一直备受关注&#xff0c;但企业往往会将50%以上的预算花在基础设施和执行上。因此&#xff0c;了解十大科技趋势与其对IT和执行的影响十分必要。在本周的Gartner CIO峰会期间&#xff0c;Gartner…

C++读取INI文件

Windows操作系统专门为此提供了6个API函数来对配置设置文件进行读、写&#xff1a;GetPrivateProfileInt() 从私有初始化文件获取整型数值GetPrivateProfileString() 从私有初始化文件获取字符串型值GetProfileInt 从win.ini 获取整数值GetProfileString 从win.ini 获取字符串值…

专栏 | 李航教授展望自然语言对话领域:现状与未来

来源&#xff1a;机器之心摘要&#xff1a;原华为诺亚方舟实验室主任、现已加入字节跳动 AI Lab的李航教授近日发表博客&#xff0c;对自然语言对话领域的现状和最新进展进行总结&#xff0c;并展望了未来的走向。1. 引言语音助手、智能客服、智能音箱、聊天机器人&#xff0c;…