C 语言是一门很难的编程语言,不懂编译原理、操作系统和计算机体系结构很难学明白...

2018-09-29 17:10:43 +08:00
 ChristopherWu

看以前自己写的一篇文章时有感: https://yonghaowu.github.io//2018/03/05/C_is_not_easy/ 萌新一个,抛砖引玉,欢迎 v 友指点

/* #include <stdio.h> */
/* #include <malloc.h> */
int main(){
    char *c = malloc(10);
    c[0] = 'a';
    printf("hi, ");
    printf("%s\n", c);
    free(c);
    return 0;
}

为什么这个程序缺了头文件, 依然可以正常编译运行, 并且有正确的结果?


/* #include <stdio.h> */
/* #include <malloc.h> */
/* #include <assert.h> */
int main(){
   char *c = malloc(10);
   c[0] = 'a';
   printf("hi, ");
   printf("%s\n", c);
   assert(c[0] >= 0.0);
   free(c);
   return 0;
}

为啥这个程序, 加了 assert 又不行了呢?


  1. #include 只是把头文件引入进来, 头文件的作用是 包含函数的原型。
  2. linker (链接器)在链接这一步时,会根据头文件函数的原型去找. o 文件中的函数,然后链接进来
  3. 对于找不到的函数,各个编译器处理会有不同。gcc、clang 会推断这个函数的原型,如 printf 就是 void printf(char *c, char)
  4. 推断了原型后,因为每个 C 程序都默认会链接 stdlib 库( gcc 编译里有 nostdlib 选项,即不去默认链接 stdlib 的库),所以你正确的使用这个 C 语言函数,也是会找到对应的正确函数
  5. 所以程序编译时会有警告,依然编译通过,并且能正确运行。

那为什么 assert 就不行了呢? 因为 assert 是一个宏,而不是函数,所以编译器不会像上述那样去处理。当没有引入 assert.h, 编译器便当它是函数来处理,最终 stdlib 里也找不到 assert 这个函数,就报错了。

7142 次点击
所在节点    程序员
45 条回复
crist
2018-09-29 21:28:08 +08:00
人生苦短,我用胶水语言 Python~
linxu
2018-09-29 21:54:34 +08:00
@LuffyGu php 是 c 写的
d18
2018-09-29 22:00:34 +08:00
我喜欢 C 语言,简单明了,没有黑魔法。
zjsxwc
2018-09-29 22:05:26 +08:00
@d18

信你有鬼了,各种骚宏,多到你怀疑人生
newtype0092
2018-09-29 22:16:17 +08:00
@zjsxwc 别的时髦语言使用了魔术道具,自己拿来学学就能露两手,C 是直接当着你的面玩无影手,原理全部告诉你,看完还是一脸懵逼。。。
zwh2698
2018-09-29 22:21:36 +08:00
瞎说,谭浩强的二级 c 语言书中前面几章就有讲这个问题。
bobuick
2018-09-29 22:34:18 +08:00
c 光语法对话,很简单了。
难的是,习惯了 web 开发的高级语言,各种库拿来操一下就出成果了。换成 C,操一个月不一定出来。
xiyiailoli
2018-09-29 22:47:47 +08:00
⊙∀⊙!差不多同意,我学了操作系统后也有这种感觉,但现在有精力研究 c 还不如去 c++吧
jecshcier
2018-09-29 22:48:51 +08:00
@bobuick 哇操一个月都不出来,说明耐操阿,多爽,手动斜眼
xeaglex
2018-09-30 00:12:32 +08:00
我觉得是你没有习惯而已,C 的设计还是非常简洁优雅的,不像 CPP
jiang42
2018-09-30 01:03:59 +08:00
@xeaglex 請回答,Cpp the good part 又名?🤪
inoki
2018-09-30 01:33:17 +08:00
手动 at 一下正在学的 x86 asm 和 arm 汇编😂
Raisu
2018-09-30 07:49:09 +08:00
@ChristopherWu 什么叫理解?我还见过看完做完 算法导论 所有习题也只有几 K 的人啊
kljsandjb
2018-09-30 08:18:02 +08:00
内功不是看书看的,看完书把习题做好 lab 吃透才算有效果
ww2000e
2018-09-30 08:30:45 +08:00
c 少个结束符啊,s%凑巧给你打出来了
cgpiao
2018-09-30 08:41:53 +08:00
我选 php 和 kotlin
python 用着好难受,标准库用起来更糟心
leido
2018-09-30 08:57:29 +08:00
@ww2000e 说的对,malloc 根本不保证初始化内存
cangshui
2018-09-30 09:21:07 +08:00
小爱同学,帮我做一下 c 语音课后习题
Chenamy2017
2018-09-30 09:31:45 +08:00
学好 C 语言,就能理解计算机很多根本的问题了!
nekoneko
2018-09-30 09:34:15 +08:00
@Raisu 看完算法导论,发现我的高数水平提升了。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/493916

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX