为何不精通C? 01一些零碎的混淆知识

引言---

     一直以来,我以为能在简历上写上“精通C语言”, 可是,朋友都劝阻说,还是写“熟悉or掌握”吧,要不然,会被问得很死的。我算是没认清现实吧,去网上找了些题,看了看,大体脉络掌握还行,但是细节部分,就很差劲了。我想起了段誉和慕容复的故事:“段誉仅精通六脉神剑,却稳胜以彼之道还施彼身的慕容复”。 C 语言既然作为我"Hello World!" 的引路人, 我很想说,我很想,精通你。

主要阅读材料: 《C专家编程》

主要记录我还未掌握,或者掌握不精的内容。

1, 合法的赋值形式, 类型的兼容

  • 问题来源:
1 foo(const char** p){}
2 main(int argc, char** argv)
3 {
4     foo(argv);
5 }

这里,定义了foo函数,具有一个 const char** 类型的形参。main函数调用foo, 将 argv 作为实参传入, 若是编译,则会有一条警告信息:

line 4: warning: argument is incompatible with prototype
  •  为什么会迷惑?

    若实参是char*,形参为 const char*, 则不会报这个警告信息,因为,他们是兼容的。

  • 理论上的解释

     来自ANSI C标准的解释:

         条件 1,两个操作数都是指向有限定符(const等)或无限定符的相容类型指针,

         条件2, 左边指针所指向的类型必须具有右边指针所指向类型的全部限定符。

  • 问题解决:

    a, char* p; const char* cp; cp=c;  : 这里,左操作数cp是具备 const限定符 的 char*; 右操作数是 char* , 左边集合为[const], 右边为[],左边包含右边所有,条件2合法;类型都为char*,条件1合法,所以通过。

    b, char** p; const char** cp; cp = p; 这里,p 是一个指向 char* 的指针, cp是一个指向 const char* 的指针。 限定符都为[],条件2符合,但是,const char* != char* 条件1不合法,所以警告。

  • 引出心得

     虽然 const 是好东西,但是不深入了解,还是很难驾驭,慎重!另外,提出了原型prototype的概念,及“兼容”理念,需要深入探究。

2, const 我们所理解错的地方

    关键字 const 并不把变量变成常量! const仅是说明了被它限定的东西,不可被赋值,即 read only!

    int const* k, const int* p 和 int *const q 区别: 最简单的做法,从右往左看,是先出现*还是const

  • 解释:

     对于 k/p而言,先看到了*,所以我们知道k/p被声明成一个指针,它指向了一个被const限定int型变量。即指针可以赋新值,但是它所指之物不能被修改。

     对于 q 而言,先看到了const, 则说明 q 具有const属性,然后看到了*,说明q是一个指针,接着是 int, 说明它指向int型变量,合起来就是:q是一个常量指针,指向int型变量。即指针不能赋值,但是其所指之物可以被修改。

  • 进阶: 见 后续博客, 大概是将声明时引入。

3, strlen()函数返回的字符串长度不包含最末尾的'\0'。对于这个知识点比较了解,但是也是因为熟悉,在使用malloc时更加容易疏忽。

     若是见到  malloc(strlen(str)); 那么,几乎可以肯定是错误的,它疏忽了最末尾的'\0', 应该 malloc(strlen(str)+1);

4, NUL != NULL

     NUL:一个ACSII字符, 表示0的位模式。

     NULL:  指向哪里也不是,一般是0;

5, break 从哪跳出,跳向哪里?

    break可以使用在for, while, do-while, switch中,用于跳出离他最近的那层循环或者switch语句。它不会跳出if语句。

 

 

posted @ 2013-05-17 01:37  xield  阅读(262)  评论(0编辑  收藏  举报