大神是如何玩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控件的一些开发方法,我们聊了如 ... 
随机推荐
- win7配置nginx+php步骤
			1.下载nginx: http://www.nginx.cn/nginx-download 2.下载php : http://www.php.net/downloads.php (线程安全与非安全参 ... 
- 如何让静态库中的可执行程序不调用的函数不链接进该可执行程序?(-ffunction-sections  -Wl,--gc-sections)
			关键词: -Wl,--gc-sections -ffunction-sections 链接 elf 库 有时我们会遇到这种情况,可执行程序需要链接一些静态库,但是静态库中的函数并没有全部使 ... 
- IOS 弹出菜单的动态效果
			效果1.点击按钮上浮 2.点击按钮下沉 3.点击按钮下拉展示 4.点击按钮向上收缩 5.左右如是说 关键是改变视图的大小位置的时机正确与否 eg1.1.点击按钮下沉消失 已知myView.frame= ... 
- IOS 使用webview 显示 doc/docx/xls/pdf等
			在一款项目里添加阅读各种文档功能 那么对在线的文档或者是下载后的文档 进行阅读,比如 doc/docx/xls/pdf等文件 有两种方法总结如下: 1. - (void)viewDidLoad { [ ... 
- iOS 抓取 UIwebview 上 所有 图片 并进行滚动播放
			关于在UIwebview上添加滚动图片 两种滚动手势会混淆,应为webview有webview.scrollview的属性 故参照昨天的随笔 scrollview嵌套解决方案. 本篇随笔主要讲循环使用 ... 
- iOS 下拉刷新 上拉加载实现原理
			1.下拉刷新 实现原理 if (scrollView.contentOffset.y < -100) { [UIView animateWithDuration:1.0 animations:^ ... 
- linux_jvm_jhat_dump内存分析
			jhat命令 jhat命令 -- Java Head Analyse Tool 用途:是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询 ... 
- jQuery中each的break和continue
			each实质上是一个for循环,那么能不能像普通的for循环那样break和continue呢? 参考http://bevisoft.iteye.com/blog/641195做了个实验,可以的, 代 ... 
- jquery plugins —— datatables 增加行号
			table = $("#Table").DataTable({ "rowCallback": function (row, data, dataIndex) { ... 
- 剑指Offer08 二进制中1的个数
			/************************************************************************* > File Name: 08_NumOf1 ... 
