0%

By Long Luo

注:
本文是从之前个人网站成长·漂泊·随想移植过来的。

一、简单与复杂

一生二,二生三,三生万物。

三年前,当自己在学校图书馆看书时,突然心里深处涌出的一种冲动,让我重拾幼年时未能发育的音乐细胞时。当时以迅雷不及掩耳之势去借了几本乐理书,认真研读,虽然到现在还是一无所成…

但音乐那种组合之美,却让我回味至今。从古至今,世间音乐不过是几十个音符组合而已,都在一架钢琴的诠释范围之内。我想起了DNA里面的4对碱基对,地球上缤纷复杂的生命均以其为基础。

如同五彩缤纷的万花筒拆开之后,却只是一些小纸片和玻璃而已

可是我想通了此节之,却不能流畅地在吉他上弹奏一曲最简单的《欢乐颂》,也分辨不了不同的和弦,听不出歌曲的调式…

凡此种种, 都需要技术,尤其是复杂艰辛的训练,几年前就期望自己能够在舞台上一展才艺,可是到现在依然达不到登台的水平。

一边憎恶虚荣,一边找各种机会虚荣,在应该为了虚荣而努力的时候,拖延症又犯了。

知道复杂是由简单的东西所构成这很容易,但是如何能将简单组合成复杂以实现某种功能这才是道,也是我所追求的。

阅读全文 »

By Long Luo

一、引言

在上一篇 深入剖析printf函数(上):如何不借助第三方库在屏幕上输出"Hello World"? 里,我们已经实现了用汇编语言在屏幕上输出了“Hello World”, 迈出了万里长征的第一步,但是我们知道实际的printf的功能是十分强大的,它和scanf一样属于标准输入输出的一种格式化函数,我们一般是这样使用它的:

1
printf()的基本形式:printf("格式控制字符串",变量列表);
阅读全文 »

By Long Luo

前言

—“你为什么要去登珠穆朗玛?”

当美国《纽约时报》记者问英国登山家乔治·马洛里。

—“Because it is there(因为山在那里)。”

一、 内核的诱惑

会当凌绝顶,一览众山小。

内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性

几十年来,内核以它那深深的魅力吸引着无数的码农为之倾倒,一代又一代的码农们从青青葱葱走向硕果累累,从风华正茂走向耄耋之年,也走出了现在多姿多彩的世界。

内核就像一位风姿卓约的美女,多少码农欲一亲芳泽而不得。Linux内核是庞大复杂的,超过 600 万行的代码,就如同珠穆朗玛峰一样那样让人望而生畏。初学者一踏入,绝大多数会不自觉地迷失在这座庞大的迷宫里。

阅读全文 »

By Long Luo

引子

大话Structure(结构体)这一系列文章来的是很偶然的。

12月初由于奶奶病故,在返家的火车上,心情比较沉重,方圆20米范围内又扫描不到一个美女,百无聊赖,于是就构思了很多文章,这一系列只是其中之一。回深圳之后,就在平时参考了不少资料,尽量用轻松幽默的语言来完成这一系列文章。

目前这一系列文章中不少内容仍然有很多欠缺,比如共同体、位域、枚举、Struct在tcp/ip中的应用等内容,这些都会在以后的文章中一一补上,敬请关注本人的博客O(∩_∩)O~

目录

Updated by Long Luo at 2016-6-12 23:18:27 @Shenzhen, China.
Modified by Long Luo at 2018年9月28日23点14分 @Hangzhou, China.

By Long Luo

前言
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第八篇: 大话结构体之八:C语言Struct中的函数和函数指针


在系列之三大话结构体之三:借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白…,我们在文章的结尾留了一个悬念:

我们了解到C语言规范是struct里面是不能有函数体的,但是在应用中假如struct中没有函数的话,我们会遇到很多问题,第一数据往往是依附于函数来进行操作的;其二是我们需要用C来实现面向对象的思想

比如下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

struct FuncInside
{
int mA;
void func()
{
printf("Hello, function inside!\n");
}
};


void main(void)
{
struct FuncInside f;

f.mA = 99;
f.func();

getchar();
}

编译会提示:

1
1>e:\learn\vs\struct\struct\funcpointer.c(7) : error C2032: “func”: 函数不能是 struct“FuncInside” 的成员

那么这个问题应该如何解决呢?

一刹那,一句话在脑海中闪现,“***指针是C语言的精华。***”

啊哈,灵机一动!

阅读全文 »

By Long Luo

前言
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第七篇: 大话结构体之七:struct中0元素数组的意义在哪里?


上一回大话结构体之六:无即是有,没有成员变量的Struct(结构体),我们在文章的结尾留了一个悬念:

—为什么0元素数组在classstruct结构体之外定义就是错误的,而在classstruct中定义就是Okay的,那么结构体中的0元素数组意义何在

阅读全文 »

By Long Luo

前言
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第六篇: 大话结构体之六:无即是有,没有成员变量的Struct(结构体)


在上一篇大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下) 中,我们学习了struct的内存对齐的前世今生。

在开始本篇之前,想问大家一个问题:

---0是什么?
---呵呵,就是没有呗!
---那好,这5块钱拿去,就当抵我上次向你借的500块钱。
---什么?这哪和哪啊!这不一样
---可是你自己说的, 0就是“没有”。
---我说不清,反正不行,你必须还我500.

0是什么?
起什么作用呢?
为什么500 ≠ 5?

这节我们来讨论***0的作用***。

阅读全文 »

By Long Luo

前言:
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第五篇: 大话结构体之五:以空间换时间,Struct(结构体)中的成员对齐之道(下)


引言

在上一篇大话结构体之四:以空间换时间,Struct(结构体)中的成员对齐之道(上) 中,我们了解到struct ALIGN2struct ALIGN3的成员变量都是1个int型,1个char型及1个short型,可是它们所占的空间却1个是8字节,一个是12字节。

为什么会有这样的区别呢?

通过上篇关于对齐的介绍,我们已经猜测这是因为编译器对其作了对齐的处理所致,但是***编译器处理的细节***具体是什么呢?

在这一篇里,我们将对程序的编译,汇编,链接进行逐一分析,解开这个谜团。

不要走开,下面更精彩!

编译过程:

一般情况下,C程序的编译过程为

  1. 预处理
  2. 编译成汇编代码
  3. 汇编成目标代码
  4. 链接

这一篇我们将使用gcc对上述几个过程进行仔细分析,了解其处理细节。

首先我们看一个例子,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/************************************************************************************
** File: - Z:\code\c\Alignment\Align.c
**
** Copyright (C), Long.Luo, All Rights Reserved!
**
** Description:
** Align.c --- To learn the details of Alignment by the compiler.
**
** Version: 1.1
** Date created: 22:33:50,10/12/2012
** Author: Long.Luo
**
** --------------------------- Revision History: --------------------------------
** <author> <data> <desc>
**
************************************************************************************/

#include <stdio.h>

struct ALIGN2
{
char mA;
int mB;
short mC;
};

struct ALIGN3
{
int mB;
char mA;
short mC;
};


int main(void)
{
struct ALIGN2 aln2;
struct ALIGN3 aln3;

printf("The size of struct ALIGN2 is: %d\n", sizeof(aln2));
printf("\t aln2.mA=0x%x, aln2.mB=0x%x, aln2.mC=0x%x\n", &aln2.mA, &aln2.mB, &aln2.mC);

printf("The size of struct ALIGN3 is: %d\n", sizeof(aln3));
printf("\t aln3.mA=0x%x, aln3.mB=0x%x, aln3.mC=0x%x\n", &aln3.mA, &aln3.mB, &aln3.mC);

return 0;
}
阅读全文 »

By Long Luo

前言
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第四篇: 以空间换时间,Struct(结构体)中的成员对齐之道(上)


在开始今天的文章之前,请先看下面一道面试题:

问题: 阅读下面一段代码并回答题目之后的问题:

1
2
3
4
5
struct ALIGN
{
int mA;
int mB;
};

请问在32位系统下sizeof(ALIGN)的结果是多少?

当然这道题目是难不到广大程序员同学们滴!

在32位机器上int类型占4个字节,Struct ALIGN里面有2个int型变量,那么总共就是***8***个字节喽!

Bingo,在这个例子中,sizeof(ALIGN)的结果的确是***8***。

结构体对齐

下面,我们把代码修改一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;

struct ALIGN
{
int mA;
int mB;
};

struct ALIGN1
{
int mA;
short mB;
};


int main()
{
cout<<sizeof(short)<<endl;
cout<<sizeof(ALIGN1)<<endl;

getchar();
return 0;
}

请问输出是多少?

阅读全文 »

By Long Luo

前言
“大话结构体”系列文章写于2012年,在我的CSDN Blog上连载的,这是系列的第三篇: 大话结构体之三: 借我一双慧眼吧,让我把C++中Class(类)和Struct(结构体)看个清清楚楚明明白白…


之前一篇 大话结构体之二: 名不正则言不顺—Struct(结构体)的声明、定义及初始化,我们已经了解了C++Struct的定义方法和C中有点不一样,而且增加了一种新的类型—Class。从C的名字我们就可以知道,C是从C进化而来,“++”就是在C的基础上加了一些东西:面向对象的东西

虽然C作为一种面向对象语言,要区别于面向过程的C语言,但是在设计时,一个很重要的原则是C必须向前兼容C,必须是C的超集。这样一来就可以带来好多好处:

第一个嘛,首先呢,C就可以站在C这个巨人的肩膀上,大量过去用C编写的程序可以不加修改地在C环境下使用;
第二,把很多C程序员忽悠进C这个大坑里,为C之崛起而加班,上了贼船可就由不得你了XD

也正是因为这个原因,C中保留了Struct结构类型,并使得Struct的功能更强大,不仅仅是简单继承C的结构体,而且扩充了Struct,使得它也具有类的特点,那么**在C中,Class和Struct到底有什么区别呢**?

Talk is cheap, show me the Code!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

struct S1
{
char mA;
int mB;
};

class C2
{
char mA;
int mB;
};


int main(void)
{
S1 a;
C2 b;
cout<<sizeof(a)<<&a<<endl;
cout<<sizeof(b)<<&b<<endl;

getchar();
return 0;
}

上面这段代码非常简单,分别定义了一个Struct类型和Class类型,并输出其大小和地址,我们先看看输出结果:

Class And Struct Output

从结果我们可以看出,没啥区别啊!

阅读全文 »