大神是如何玩C语言的!
我在酷壳上看到一篇文章,C语言结构体里的成员数组和指针,看得感觉让我真是佩服地五体投地啊。皓哥虽说谦称自己不是高手啥的,但是写出这样的文章来,真是让我感觉自己的水平真是渣渣!我看完了感觉有点小激动,也想自己讲讲,试试,看看能不能讲清楚那个微博中所叙述的的问题,绝对没有抄袭的意思。由于我的水平实在有限,写的可能很糟糕,还请各位见谅!
OK,废话少说,先来说说一下问题,有这么一段代码,
#include<stdio.h>
struct str{
int len;
char s[];
}; struct foo {
struct str *a;
}; int main(int argc, char** argv) {
struct foo f={};
if (f.a->s) {
printf( f.a->s);
}
return ;
}
这个程序会在哪一行挂掉呢?我用的是gcc,我这里是在第14行挂掉的。为什么呢?为什么那个if语句那里不挂掉,而是在printf语句这里挂掉呢?
这个我们首先得分析变量是啥?变量是啥,其实就是内存区域的别名!而结构体类型的变量,其实就是一大块内存区,然后结构体变量名指向的是这块内存区的起始地址,然后根据变量的类型来不断向后推出其他变量。比如上面那个str结构体。其实就是一块4字节内存用来存放int变量len,然后后面的字节用来存放字符数组s。我们可以通过gdb打印出他们的地址,如下图所示:
这里结构体变量t和它的第一个成员len的地址都是0xbffff184,而它的s成员的地址就是t的地址+4也就是0xbffff188。OK,通过这样的叙述不知道大家能不能理解,其实结构体中每个成员的变量的地址其实就是结构体变量的地址加上相对偏移。比如上面例子中s的地址就是t的地址加上4个字节(代表int变量)。
知道了这个概念,我们来分析一下这段程序。
首先从主函数开始,建立了一个f变量,里面有一个成员是指针a,然后指针a里面存放的地址被初始化为0。然后在if语句中使用的是f.a->s,它就是找到一个地址,就是s变量的地址,寻找的方式就是先找到结构体变量指针a中存放的地址,然后再对这个地址+4,然后找到这个地址之后并没有去访问这个地址所代表的内存空间,所以程序没有报错。而在print语句中呢,也是先找到这个地址,然后去访问这个地址所代表的内存空间,试图在这个空间中寻找一串字符串并输出出来。由于a中我们已经初始化为0,所以访问的内存空间就是0x4的空间,所以程序就会挂掉了!^ o ^
大神是如何玩C语言的!的更多相关文章
- 大神是如何学习 Go 语言之 Channel 实现原理精要
转自: https://mp.weixin.qq.com/s/ElzD2dXWeldYkJmVVY6Djw 作者Draveness Go 语言中的管道 Channel 是一个非常有趣的数据结构,作为语 ...
- 大神真会玩~这组C4D动图,我都看了一整天!
来自法国的Guillaume Kurkdjian 擅长创作一些平面动态图像 每张都诉说了一个小笑话或者小故事 像个极其微型的小电影. 这些动图的灵感可能来自某个交通工具 或是某个悠闲的时光 也可能是生 ...
- C语言是菜鸟和大神的分水岭
作为一门古老的编程语言,C语言已经坚挺了好几十年了,初学者从C语言入门,大学将C语言视为基础课程.不管别人如何抨击,如何唱衰,C语言就是屹立不倒:Java.C#.Python.PHP.Perl 等都有 ...
- C语言简单实现链栈基本几个功能(适合新手看,大神可指正)
接着上一次的顺序栈,今天我记一下链栈,因为我也是刚学不久,有些地方也稍稍理解不了,所以,一起共勉.我会用我自己结合教材上画的图,争取跟代码一起结合,用文字和图最大化的解释代码,这样的话 ...
- 老猪带你玩转自定义控件三——sai大神带我实现ios 8 时间滚轮控件
ios 8 的时间滚轮控件实现了扁平化,带来很好用户体验,android没有现成控件,小弟不才,数学与算法知识不过关,顾十分苦恼,幸好在github上找到sai大神实现代码,甚为欣喜,顾把学习这个控件 ...
- 前端自学vs跟大神系统学?你看着办
前端自学vs跟大神系统学?你看着办 一名广告专业学生,在大三的时候对于广告行业的前景不是很看好,转而自学web前端,刚开始接触的前端语言是html(html应该不算编程语言),上手很容易,在w3csh ...
- [OC笔记]@property之个人理解,大神轻拍
/** * 一个简单的对象 * * @author suzhen * */ public class SimpleObjcet { /** * 声明一个age字段 */ private Object ...
- wire与reg的区别?转载大神!
本文转自:http://www.cnblogs.com/thymon/archive/2010/06/09/1754541.html //------------------------------- ...
- 兄台息怒,关于arguments,您的想法和大神是一样一样的----闲聊JS中的apply和call
JavaScript提供了apply和call两种调用方式来确定函数体中this的指向,表现出来的特征就是:对象可以'借用'其他对象的方法.之前的几篇博客回顾了一些Web控件的一些开发方法,我们聊了如 ...
随机推荐
- 基于Ascensor.js全屏切换页面插件
今天给大家分享一款基于Ascensor.js全屏切换页面插件,这款实例 适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览 ...
- Busybox支持中文的解决办法
转载:http://blog.csdn.net/wavemcu/article/details/7202908 ******************************************** ...
- jQuery之防止冒泡事件
冒泡事件就是点击子节点,会向上触发父节点,祖先节点的点击事件. 方法1: event.stopPropagation(); // 阻止事件冒泡 有时候点击提交按钮会有一些默认事件.但是如果没有通过验证 ...
- 修改avd路径
1.比如你要把AVD放在D盘AndroidAVD下面,则预先在D盘下建立一个文件夹 AndroidAVD.必须的.不然设置了环境变量也没有用,因为模拟器不会自动创建该文件夹. 2.在桌面右击“我的电脑 ...
- 1. SQL Server服务器监控实现方法
对于服务器的监控,和对数据库的监控,很少有合二为一的工具,如果有的话,一般是付费软件,或者自行开发的工具.所以如果不想购买软件,也不想花精力去开发的话,可以结合一些免费/开源的工具.自定义脚本,来完成 ...
- Windows防火墙出站、入站相关知识总结
出站默认是全部允许,只禁止相关出站规则指定的条目:入站默认是全部禁止,只允许相关入站规则指定的条目. 入站规则其实没什么好说的,直接添加规则允许某IP或端口访问,或允许某程序全部访问,就行了. 要控制 ...
- ORA-01034: 、ORA-01078: 和 LRM-00109: 的解决方法
环境:Linux 5.4 Oracle 11.2.0.3 在Linux上连接Oracle时遇到报错: SQL> show parameter sgaORA-01034: ORACLE not a ...
- ps怎么给文字描边
在设计的时候,单一的文字,往往对人没有多少的吸引力,这就需要我们在文字上加一些文字特效,比如说外发光,描边,投影,等等.在这里我们详细的介绍一下文字的输入,和文字描边的怎么增加,删除的经验.(这些方法 ...
- 剑指Offer13 链表倒数第K个结点
/************************************************************************* > File Name: 13_KthNod ...
- POJ 3921 Destroying the bus stations 沿着最短路迭代加深搜索
题目:给出一个图,问最少删除多少个点,使得从点1到点n经过的点数超过k个. 分析: 上网搜了一下,发现很多人用网络流做的,发现我不会.再后来看到这篇说网络流的做法是错的,囧. 后来发现点数有点少,直接 ...