02|程序基石:数据与量值是如何被组织的?

2021-12-08 于航
《深入 C 语言和程序运行原理》
课程介绍


讲述:于航

时长:大小15.97M


你好,我是于航。
从这一讲开始,我们就进入到了“C 核心语法实现篇”的学习。在这一模块中,我们将围绕 C 语言的七大类核心语法,深入探寻隐藏在语法背后,程序代码的实际执行细节。
C 语言让我们能够用一种可移植、结构化,且具有人类可理解语义的方式,构建我们的程序。C 标准中详细描述了 C 语言在语法和语义两个层面的基本内容,但对于实现者,比如编译器来说,如何将这些语法和语义体现在具体的机器指令(汇编代码)上,标准并未给出详细规定。
所以问题来了:在这层抽象背后,一个 C 程序中的各类语法结构,究竟是如何映射到机器能够识别的不同指令上的?相信学完这一模块,你就能找到这个问题的答案,从而对程序的运行有更细粒度的把控。
今天,我们就从最基本的数据和量值开始。相信你在第一次接触编程这个概念时就会了解到,一个完整的程序是由“算法”与“数据结构”两部分组成的。其中,算法代表程序会以怎样的具体逻辑来运行;数据结构代表程序运行过程中涉及数据的具体组织方式。而在一门编程语言中,数据便...

展开全文
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。

精选留言

  • sugar
    置顶
    2021-12-18
    挺有意思~ 我记得在本科学计算机体系结构时,教科书上对补码的定义是先取反码然后+1。于是当我见到一个int在内存中的布局时我会用上述计算步骤进行逆向操作得到原码再算出人类习惯的十进制数。 在这篇专栏里我才知道原来还有 负权重位 这么一说 是完全另外一种计算方式 得到的结果是一样的 哈哈 是个有趣的数学现象
    共 1 条评论
    17
  • 一步
    置顶
    2021-12-09
    我在 mac 环境下 可以使用 const 修饰的只读变量来指定数组长度和 switch case 的值,正常运行了 Apple clang version 13.0.0 (clang-1300.0.29.3) Target: arm64-apple-darwin21.1.0 Thread model: posix

    作者回复: 这是一个很好的发现! 你可以试着在编译指令中添加 “-pedantic -Werror” 这两个选项,然后看看结果会有什么不同?实际上 Clang 在某些情况下会采用名为 “gnu-folding-constant” 的 GNU 扩展来编译 C 代码,但这并不是 C 标准中的内容。

    共 4 条评论
    10
  • jack123
    置顶
    2021-12-08
    typedef unsigned int size_t; 具体类型还要看目标机器上的定义, 不过在一般机器上,size_t被定义成无符号整型 在一些常见C语言的函数的返回值是size_t 比如strlen,sizeof, 值得注意的是,在STL容器做遍历的时候,它里面size()方法返回值也是size_t类型的
    展开

    作者回复: 这个回答很棒!

    共 2 条评论
    9
  • Pushsadfc
    置顶
    2021-12-23
    作者大大,你关于函数是如何被调用的,我想了解更多,应该去看哪些书籍嘞。还有您有哪些好的c语言底层书可以推荐嘞

    作者回复: 关于函数调用细节,我们在第 5 和 6 两讲中有介绍的。 相关的书其实有很多哈,比如: 《CSAPP》 《Low Level Programming》 《Modern C》 《X86/64 体系探索与编程》 其他的也可以在比如 Oreilly 上搜一搜哈,它们虽然不是专门讲 C 语言底层的内容,但都是有一定关系的。推荐多参考几本,然后就能找到共通点了。

    
    2
  • pedro
    2021-12-08
    讲的好,拍案叫绝!
    
    3
  • 曙光
    2022-04-24
    负数反码= 补码+1,计算反码更简单的方法,从右向左数,数的过程中,右边到达第一个1的数,都不变,1左边的数,统一取反。 例如 补码1110 1000,反码是0001 1000。如果是取反再加一,需要0001 0111 ,再加1,也是0001 1000
    
    1
  • 纳兰容若
    2022-04-06
    老师您好 有一个问题请教一下 0 0001 001 为什么表示 0.017578 (图中)

    作者回复: 这个按照 IEEE-754 的组成结构来计算就可以。这里符号位 0 表示正数;指数位为 1,偏置量为 7,对应的阶码为 1 - 7 = -6;尾数为 0.125。所以对应的浮点数为:1.125 * 2 ^ (-6) = 0.01757812。这里 Rounding 了一下,所以变成了 0.017578。

    
    2
  • 石天兰爱学习
    2022-01-06
    #include<stdio.h> int main(int argc, char *argv[]) { int test_num1 = -10; unsigned int test_num2 = test_num1; printf("%d\n",test_num2); } 请问老师,我这个程序的结果为啥是-10,而不是一个正值呢? (Windows下VS编译环境)
    展开

    作者回复: 因为位模式不变,但这里 printf 中的格式占位符应该用 “%u” 哈。%d 对应的是 signed decimal integer。

    共 2 条评论
    1
  • Geek_fbce70
    2021-12-20
    常量如何定义,这节里没有介绍啊

    作者回复: 实际上,在代码中用到的字面值就是常量哈。在 C 语言中,常量并没有其他的定义方式。

    共 4 条评论
    1
  • 柴
    2021-12-08
    size_t:一般用于指示数据类型的大小,无符号整型

    作者回复: 正解!

    共 2 条评论
    1
  • I
    2021-12-08
    size_t 是无符号整型,常用于计数

    作者回复: 没错的。

    
    1
  • 龍蝦
    2022-02-27
    老师,这节提到几次内联,这里的内联跟内联函数的内联是否相同?

    作者回复: 是一样的哈,你可以按照同样的方式理解。就是把值、函数体,直接放到之前通过变量,或函数调用间接引用的地方。

    
    
  • 我亦无他,惟手熟尔
    2022-02-15
    const变量定义定长数组时未显示有错误,编译运行都通过了,怎么回事?

    作者回复: 可以试着在编译指令中添加 “-pedantic-errors” 这个选项,然后看看结果会不会有不同?

    
    
  • 不穿格子衬衫的程序员
    2021-12-25
    “补码”这一节中:“C 语言作为一种弱类型语言,其一大特征就是在某些特殊情况下,变量的实际类型会发生隐式转换。”这句话是笔误了吧?C 语言是强类型语言吧?

    作者回复: 这里的原意是没错的,我想突出的是 “C 变量的实际类型会发生隐式转换”这个点。但实际上,强弱类型这个评判标准本来就是模糊的,或者是不推荐使用的。因为强弱是相对的,因此我们可以说 C 的类型是比 JavaScript 强,但比 Ada 弱的。因为 JavaScript 不要求变量具有类型,但 Ada 却要求所有变量都需要有类型,并且仅支持显式的类型转换。这样一比较的话,C 只能处在两者之间。

    共 2 条评论
    
  • 友
    2021-12-16
    确实 有符号类型和无符号类型去操作的时候会被转成无符号类型 这块以前在书上也看过
    
    
  • qinsi
    2021-12-10
    #include <stdio.h> int main(int argc, char *argv[]) { const float f = 16777214; for (int i = 0; i < 10; i++) { printf("%f\n", f + i); } const double d = 9007199254740989; for (int i = 0; i < 10; i++) { printf("%lf\n", d + i); } return 0; }
    展开
    
    
  • qinsi
    2021-12-10
    #include <stdio.h> int main(int argc, char* argv[]) { const int a[] = { 1, 2, 3 }; for (size_t i = 2; i >= 0; i--) { printf("%d", a[i]); } return 0; }
    展开
    
    
  • 观弈道人
    2021-12-09
    补码那一段表示看不懂~

    作者回复: 哪里没有看懂呢?

    共 5 条评论
    
  • 石天兰爱学习
    2021-12-09
    老师讲的很好,努力学习中,打卡
    
    
  • =
    2021-12-09
    size_t是无符号整型。 它通常被用于循环中的变量声明、sizeof()的返回值类型、return返回值类型、malloc()分配空间大小的表示、数组大小的表示等。
    
    