C指针乱谈(1)
写了几年的C指针几乎没怎么用过,因为感觉没什么用。不过在听了一位老师讲课之后,我改变的我的想法。
在此稍做总结,希望能帮到一些和我有同样想法的人,希望看完这篇文章后能改变您的想法。
首先,说说概念,指针是什么?基本的作用是什么?
答:指针它本身就是一个变量,它的作用就是用来保存地址。
有了这个概念,我们继续向下看。
指针的声明:
char* p; //这就声明了一个char型 的指针,名字叫p
这里,我要强调一点,这一点十分重要,对理解指针十分有帮助。请注意,我声明指针时*号是挨着char的且和p之间有一个空格,
为什么这么写?(虽然我们知道有没有空格都无所谓,对结果没影响)这样写就是为了明确char*它是一个整体,它表示的是一种类型!
一旦你这么看,那么在很多时候你就不会犯糊涂.比如: 我们在初始化指针的同时为指针赋值,如下
//形式1
int a[]; //声明一个数组
char* p = &a[]; //将指针指向数组的第一个元素
//形式2
int a[];
char* p;
p = &a[];
形式1,和形式2是完全等价的,我们看形式2,就得很清晰,看形式1,就觉得别扭!原因是,我们认为指针是和地址是对应的,
有的时候甚至认为指针就是地址,所以形式2中将一个地址赋值给指针,太自然不过了。
但形式1中 char* p = &a[0]; 就让人感觉地址赋值给了*p,而*p代表的是地址中的值啊!所以看起来别扭。但是如果按照我之前
的说法“char*它是一个整体”,你还觉得别扭吗?那么那种别捏的感觉是不是消失了呢?
在此,引出一条经典的结论:
在定义变量用到的符号都不表示运算,而表示是一种类型!
指针,就是一个很好的例子,char* p = &a[0];是*表示指针类型,而用的时候,如:a[0] = *p, *表示一种操作(将p指向地址的值取出来)
同样数组也是这样:int a[5]; []表示是数组类型,而用的时候*p = a[0];[0]表示将0位置这个取出来。
指针的声明拓展:
const data* p;//表明该指针只能用于读取数据而不用于修改数据
最终结论: 声明指针时,将类型和*看作一个整体,它表示一种类型。
上述的只是一个开场白,接下我们来看一看,指针的好处,让我们知道,用指针用的有道理。
这里,我就从结构体指针入手,为什么从他入手,因为指针在这方面用的比较多(相比,指向数组的指针就用的比较少,优势也不大)
在此,提前引入一条经典结论:传递结构体变量时,总是传递地址,而不是变量本身。
#include <stdio.h>
typedef struct date{
int year;
int month
int day
}date; void print(data d)
{
printf("%d年%d月%d日",d.year,d.month,d.day)
} void main()
{
data a[]={{2012.7.},{2013.8.},{2013.9.}};
int i;
for(i=; i>; i++)
print(a[i]); //这里的参数传的就是结构体变量本身
}
所以data a[3]表示声明了一个结构体数组,(类比于int a[3],因为data表示一个类型)感觉就像一个二维数组。
当然,这都不是重点,重点是他违背了一句话:传递结构体变量时,总是传递地址,而不是变量本身。显然void print(data d)这个函数
传递的是变量本身,那么就意味着系统将为形参d将开辟一个空间储存一个结构体变量,也就是 year,month,day这3个int型变量。如果
结构体比较大,这样就很浪费内存空间了,那如何实现传递地址呢?答案就是用结构体指针,不管结构体有多大,我只用开辟一个指针大小的
空间,这样是不是节约了空间呢,同时也节省了时间,这种好事何乐而不为呢?具体看如下代买:
#include <stdio.h>
typedef struct date{
int year;
int month
int day
}date; void print(const data* p)//同样data*看成一个整体
{
printf("%d年%d月%d日",p->year,p->month,p->day)
} void main()
{
data a[]={{2012.7.},{2013.8.},{2013.9.}};
int i;
for(i=; i>; i++)
print(&a[i]); //这里的参数传的就是结构体的地址
}
p->year,p->month,p->day表示用指针来访问结构体变量。
也可以写成:(*p).year,(*p).month,(*p).day,至于为*p打上括号,原因是"."的优先级(仅次于圆括号)比“*”的优先级高。
好了,就聊到这吧!希望能帮到阅读到此的读者。
C指针乱谈(1)的更多相关文章
- 微软ASP.NET技术“乱谈”
微软ASP.NET技术“乱谈” 2014新年了,顺手写的一点文字,主要谈谈我对当前微软ASP.NET技术的看法,比较随意,大伙儿随便看看吧. 1 当前微软Web平台技术全貌 从2002年发布.NET ...
- C++矢量图形库系列(1)——矢量图形库乱谈(转)
转自:http://blog.sina.com.cn/s/blog_4265e1760100lg03.html 本系列篇章的主要内容是讲解矢量图形库的编译.开发和使用.并不对他们周边的内容做过多的描述 ...
- 优测优社区干货精选|老司机乱谈编辑器之神——vim
文 / 腾讯 吴双 前言 优测小优 有话说: 腾讯优测只有应用测试大神?不不不,我们还有各种研发大牛! *** vim 是一种信仰,我自从2004年有了这个信仰,已经12个年头了.本文介绍了学习vim ...
- [转]vnpy乱乱谈 02架构
vnpy乱乱谈 02架构 转自:http://101.132.65.227/?p=51 听到架构这个词先不要害怕. 其实这部分内容还是挺简单的. 一般而言, 一个交易系统我们可以简单的分成输入, (系 ...
- MacBook鼠标指针乱窜/不受控制问题的解决方法
用了快一年的MacBook Pro最近出现了奇怪的问题.出问题时,鼠标不受控制,屏幕上鼠标指针乱窜,还时不时自动点击,犹如电脑被人远程控制一般.不管是用trackpad还是用外接鼠标,都是同样问题.电 ...
- JIT-动态编译与AOT-静态编译:java/ java/ JavaScript/Dart乱谈
C 和 C++ 之类的编译语言性能远超Java,但是生成的代码只能在有限的几种系统上执行,这就有了Java的存在基础(JVM-跨平台) 早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之 ...
- QString 乱谈(1)
一个月前尝试写了一篇关于QStringLiteral,存盘时MoinMoin罢工了.吸取一点经验,还是写成短篇吧 可是,可是,QString不就是简简单单一个字符串么?能有什么可谈的.真的么... ( ...
- 乱谈Qt事件循环嵌套
本文旨在说明:QDialog::exec().QMenu::exec()等开启的局部事件循环,易用的背后,还有很多的陷阱... 引子 Qt 是事件驱动的,基本上,每一个Qt程序我们都会通过QCoreA ...
- 小小换行符乱谈(文本文件vs二进制文件)
使用 C 语言的 fopen 打开文件时,可以指定的 mode 有 12 个,其中 6 个包含 "b" 使用 C++ 的 fstream 打开文件时,可用的模式组合有 24 个( ...
随机推荐
- 2018-10-19 00:13:35 ArrayList
获取集合元素的长度用的是size方法. 传入Object类型的值,返回boolean值的remove方法,含义是判断是否删除成功. 传入索引值的remove方法,返回的是被删除的元素. 修改值得set ...
- 团队项目第二阶段个人进展——Day1
一.昨天工作总结 冲刺第一天,查看了第一阶段的代码 二.遇到的问题 写个的代码发现看不懂了 三.今日工作规划 重新设计页面布局
- 互联网,IT,大数据,机器学习,AI知识tag云
互联网基础: tcp/ip网络,linux运维,DNS,ipv6 web前端: javascript, es6, 组件化开发, vuejs, angularjs, react html5, css3, ...
- 在 Windows 上创建虚拟机规模集和部署高度可用的应用
利用虚拟机规模集,可以部署和管理一组相同的.自动缩放的虚拟机. 可以手动缩放规模集中的 VM 数,也可以定义规则,以便根据资源使用情况(如 CPU 使用率.内存需求或网络流量)进行自动缩放. 在本教程 ...
- 分享一个基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具
soar-web 基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具,支持 soar 配置的添加.修改.复制,多配置切换,配置的导出.导入与导入功能. 环境需求 python3.xF ...
- Django接收URL问号参数
问题概览: 一开始需求是想通过URL接收参数,但是一直固守通过正则表达式的方式接收参数,即形如(?P<parm>.+)的方式. 后面发现(/?)在http://regex101.com是可 ...
- SQL 性能不佳的几个原因
•不准确的统计数据•差劲的索引•差劲的查询设计 •差劲的执行计划,通常是由不正确的参数引起的•过度阻塞和死锁 •非基于集合的操作•不良数据库设计 •过度碎片 •不能重复使用执行计划 •查询频繁重编译 ...
- 分布式全局ID生成器设计
项目是分布式的架构,需要设计一款分布式全局ID,参照了多种方案,博主最后基于snowflake的算法设计了一款自用ID生成器.具有以下优势: 保证分布式场景下生成的ID是全局唯一的 生成的全局ID整体 ...
- sourceTree跳过注册
sourceTree是一个很方便的git管理工具,但是现在一直无法注册,本文记录了跳过注册的方法. 将下面的代码赋值到地址栏 %LocalAppData%\Atlassian\SourceTree\ ...
- PHP判断用户是否手机访问
自定义的函数如下: $agent = check_wap(); if( $agent ) { header('Location: http://www.nowamagic.net'); exit; } ...