大神是如何玩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控件的一些开发方法,我们聊了如 ...
随机推荐
- Preventing CSRF in Java web apps---reference
reference from:http://ricardozuasti.com/2012/preventing-csrf-in-java-web-apps/ Cross-site request fo ...
- Working with MTD Devices
转:http://www.linuxforu.com/2012/01/working-with-mtd-devices/ Working with MTD Devices By Mohan Lal J ...
- Play on Words 欧拉通路(回路)判断
Play on Words note: 判断一下连通性. #include <iostream> #include <cstdio> #include <cstring ...
- android 内存优化以及性能优化相关问题
最近做一个android 的应用程序 总是出现内存高 和cpu高的问题困扰了好多天. 下面为自己从网上总结的和自己找到的问题. 1. WebView 控件: 使用了 WebView 控件一定要注意清 ...
- ASP.NET页面与IIS底层交互和工作原理详解(第一回)
引言 我查阅过不少Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net.他们耐心.细致地告诉你如何一步步拖放控件.设置控件属性.编写CodeBehind代码,以实现某个特定 ...
- python学习好书推荐
1. 编程小白的第一本 Python 入门书 http://www.ituring.com.cn/book/1863 点评:知识体系全面,作者也是功底深厚.对全面了解python非常有帮助.入门级推 ...
- Camera 幻灯片播放
Camera 幻灯片播放与轮播有些类似,不同的是在camera 幻灯片播放时有很多很炫很酷的播放效果 : 简单的介绍Camera 插件的使用方式: 1.引入js: <script src=&qu ...
- springmvc的一个小例子学习(一)
个人觉得,学框架最好的 方法无外乎两个:一个是实践这个框架,真实的去用它,比如spring框架,先搭一个简单的spring项目,然后一步一步得去丰富它,从中学到spring框架的精髓和知识:另外一个就 ...
- 每天一道LeetCode--371. Sum of Two Integers
alculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Examp ...
- hihocoder#1054 : 滑动解锁(深度优先搜索)
描述 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上 ...