C语言笔记---杂记

 

C语言笔记---杂记

 

        此篇笔记不是C语言具体某个知识点的介绍,而是在学习C语言过程中,把遇到的觉得有意义的知识点记录下来。在那么多C语言的知识点中,难免有所遗漏,所以把这些遗漏的、凌乱的、好玩的知识点统一记在这一篇中。

(此篇只做简单笔记,并不进行深入剖析)

 

一、关键字(32个)

很多人对各种高级编程语言的关键字都似是而非,而且确实有些关键字也容易被人忽略。下面,我就罗列一下C语言标准定义的32个关键字

 

 

                     C语言标准定义的32个关键字

            关键字                          含           义

            auto                             声明自动变量,缺省时编译器默认变量为auto(比较废柴的关键字)            

            int                                声明整型变量

            double                        声明双精度变量

            long                             声明长整型变量 

            char                             声明字符型变量

            short                            声明短整型变量

            signed                         声明有符号类型变量

            unsigned                    声明无符号类型变量

            struct                           声明结构体变量

            union                          声明联合数据类型

            enum                          声明枚举类型

            static                           声明静态变量

            switch                         选择结构---开关语句

            case                            选择结构---开关语句执行分支

            default                       选择结构---开关语句执行的“其他”分支

            break                          结束,跳出当前循环、选择语句

            continue                    结束本次循环,进行下一次循环

            register                       声明寄存器变量

            const                          常量---声明只读变量

            volatile                       说明变量在程序执行中可被隐含地改变

            typedef                      给数据类型取别名

            extern                         声明为外部变量(声明变量是在其他文件正声明---也可以看做是引用变量)

            return                        子程序返回语句(可带参,也可不带参)

            void                           声明函数无返回值类型或无参数,声明空类型指针

            do                              循环体

            while                          循环条件

            if                                 条件判断语句

            else                            条件语句,与if连用

            for                              for循环

            goto                           无条件跳转语句

            sizeof                         计算对象所占内存空间的字节数

 

各个关键字细解:

auto:编译器在缺省情况下,所有变量都默认是auto,可以当其不存在。有点废

 

register:声明寄存器变量。作用是请求编译器尽可能(不是绝对)的将变量存放在CPU内部寄存器中,而不是通过内存寻址的方式访问,那样可以提高效率。CPU寄存器数量有限,因此要宝贝对待。什么是寄存器呢?寄存器其实就是一块块小的存储空间,打个比喻,把CPU比作皇帝,那么寄存器就是皇帝身边的小太监,各个内存空间就相当于文武百官。CPU不是直接和内存打交道,需要通过寄存器中转,内存中的数据需要先存放到寄存器中,然后CPU再从寄存器中读取数据进行处理,处理完后再把数据通过寄存器存放回内存。上述过程就好比文武百官写了奏折(数据),皇帝不会亲自跑到百官家里去拿奏折(电视里面也是这么演的),奏折先交个皇帝身边的小太监(寄存器),然后再拿给皇帝处理。声明为寄存器变量,近水楼台先得月,直接交给CPU处理了,不需要通过内存寻址访问那么大的内存了,肯定是效率最高的。那么有人可能会问,既然寄存器效率那么高,为什么不把我们的内存硬盘都改为寄存器呢?我只能说,收买皇帝身边的小太监太贵了,收买不起。

注:寄存器速度快,因为直接和CPU打交道,因此register修饰的变量必须是能够被CPU寄存器接受的类型。register变量必须是一个单个的值,长度小于或者等于整型长度。register变量可能不存放在内存中,所以不能用取址运算符“&”来获取register变量的地址。

 

staitc与extern : 

1.static:

1>修饰变量:

变量分局部变量、全局变量

局部变量:在函数内定义,就只能在这个函数里使用,同一个文档的其他函数也无法使用。如果被static修饰,那么该变量存放在内存的静态区,所以即使函数运行完毕,这个静态变量的值也不会被销毁,函数下次使用仍然能使用这个值。

全局变量:被static修饰,静态全局变量,作用域仅限于变量被定义的文件中,其他文件即使用extern声明也没法使用它。准确地说作用域是从定义之处开始,到文件结尾处结束,在定义之处前面的那些 代码行也不能使用它。

注:被static修饰的变量都存放在内存的静态区

 

2>修饰函数:

被static修饰的函数变为静态函数。此处的“static”含义不是指存储方式,而是指对函数的作用域仅局限在本文本(所以又称内部函数)。使用内部函 数(静态函数)的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。

 

小结:static含义:1.表示退出一个块后仍然存在的局部变量。2.表示不能被其他文件访问的全局变量和函数。

 

2.extern:

extern,外面的、外来的意思。。extern 可以置于变量或者函数前,以 标示变量或者函数的定义在别的文件中,下面的代码用到的这些变量或函数是外来的不是本文件定义的,提示编译器遇到此变量和函数时在其他模块中寻找其定义。就好比在本 

文件中给这些外来的变量或函数带了顶帽子(标记),告诉本文件中所有代码,这些家伙不是土著(不是定义在我们这个文件的),去其他文件找它们的定义。 那你想想extern 修饰的变量或函数是定义还是声明?------明显是声明,起到告知、通知的作用,仅此而已。

 

static与extern作用总结:

1.变量:

1>static:定义局部变量(延长局部变量的生命周期,函数退出,被static修饰的局部变量不会被销毁,直到整个程序退出才被销毁)

                 定义全局变量,静态全局变量,作用域仅限于变量被定义的文件中

2>extern:声明全局变量

 

2.函数:

1>static: 声明和定义内部函数(内部函数只能被本文件访问,不能被其他文件访问。不用担心不同文件的函数同名问题)

2>extern:声明和定义外部函数(缺省默认为extern,外部函数可以被本文件和其他文件访问)

 

 

 

二、C语言数据类型:

基本类型   char    short    int    float    long   double

构造类型   数组    结构体struct    共用体union    枚举类型enum

指针类型

空类型   void

 

 

三、定义与声明的区别

int   i;          

extern   int  i;

上面两个,哪个是定义,哪个是声明呢?

定义:(编译器)创建一个对象、变量,给该对象分配内存空间并给它取一个名字(对象名、变量名),一旦这个名字和这块内存匹配起来,它们就同生共死,并且这块内存的位置(地址)也不能被改变。一个变量或者对象在一定区域内(函数内、代码块内)只能被定义一次。如果定义多次,到时候根本不能确定该使用哪个了,因此编译器会提示重复定义同一个变量或者对象。

 

声明告诉编译器,此名字(变量名或对象名)已经与此内存匹配在一起了,别的内存空间不能用此名字作为变量名或对象名,起到告诉通知的作用,并未正确分配内存空间声明可以出现多次(相当于多通知了编译器几次,没什么大碍)。

int   i;     //定义变量i

extern int   i;     //声明变量i

 

定义与声明最大的区别在于:定义是创建对象并为该对象分配内存;声明没有真正的分配内存(可以理解为口头通知而已)。

注:定义变量的同时别忘记初始化,因为定义变量时编译器并不一定清空了这块内存,其值可能是无效数据。

 

 

四、if和else简单笔记(此处不做详细分析)

else用来与if语句配对,如果有多个if嵌套使用时,该怎么匹配呢?C语言这样规定:else始终与同一括号内最近的未匹配的if语句匹配。if、else语句后面的{}不建议省略。

初学者往往容易在if语句后面加上分号;

例如 if(a>0) ;

分号;也是一条语句,空语句,要小心使用。否则后患无穷。

 

五、switch和case

if、else一般表示两个分支或者嵌套表示少量的分支,如果分支多了,使用switch、case组合更明了。

1.每个case语句的结尾绝对不要忘了加break,除非程序需要省略break

2.最后必须使用default 分支,即使程序真的不需要default 处理,也应该保留

3.case关键字后面只能是整型、字符型常量或常量表达式。

 

六、do、while、for关键字,break、continue

C语言3中循环结构:while循环、do-while循环、for循环

while循环:先判断条件,再执行循环体。循环体可能一次都不会被执行。

do-while循环:先执行循环体,再判断条件。循环体至少被执行一次。

for 循环:for循环可以很容易的控制循环次数,多用于事先知道循环次数的情况下。

break:终止本层循环,跳出本层循环体,执行循环语句后面的代码。如果只有一层循环,那么break就终止循环。

continue:终止本次循环,直接进行下一次循环。

在多重循环中,如果有可能,应当将最多次数的循环放在最内层,最少次数的循环放 在最外层,以减少CPU 跨切循环层的次数。

不要在for 循环体内修改循环变量,防止循环失控,例:

for (i = 0; i < 10; i++)

{

    …

    i = 8;//不可,容易循环失控

    …

}

把循环嵌套控制在3 层以内。国外有研究数据表明,当循环嵌套超过3 层,程序员对循环的理解能力会极大的降低。如果你的循环嵌套超过3 层,建议你重新设计循环。

 

七、return关键字

return关键字用来终止一个函数,并返回其后面跟着的值。

return 语句不可返回指向“栈内存”的“指针,因为该内存在函数体结束时 被自动销毁。

 

八、const关键字

const 是constant 的缩写,是恒定不变的意思,也翻译为常量、常数等。所以很多人认为被const修饰的是常量,其实精确来说,应该是只读的变量,应该叫做readonly更加贴切。

const 修饰的只读变量具有不可变性,必须在定义的同时进行初始化。

编译器通常不为普通const 只读变量分配存储空间(节省空间,避免不必要的内存分配),而是将它们保存在符号表中,这使 得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。

 

 

 

九、struct关键字

作用:结构体,将一些相关联的数据打包成一个整体,方便使用。

结构体所占的内存大小是其成员所占内存之和(不考虑内存对齐)。

 

那么空结构体占多少内存空间呢?答案是1个字节

struct Book

{

}book;

sizeof(book)的值是多少呢?测试一下,不是0,而是1。为什么呢?你想想,如果我们把struct Book 看成一个模子 的话,你能造出一个没有任何容积的模子吗?显然不行。编译器也是如此认为。编译器认为任何一种数据类型都有其大小,用它来定义一个变量能够分配确定大小的空间。既然如此,编译器就理所当然的认为任何一个结构体都是有大小的,哪怕这个结构体为空。那万 一结构体真的为空,它的大小为什么值比较合适呢?假设结构体内只有一个char 型的数据成员,那其大小为1byte(这里先不考虑内存对齐的情况).也就是说非空结构体类型数据最少需要占一个字节的空间,而空结构体类型数据总不能比最小的非空结构体类型数据所占的空间大吧。这就麻烦了,空结构体的大小既不能为0,也不能大于1,怎么办?定义为0.5个byte?但是内存地址的最小单位是1 个byte,0.5 个byte 怎么处理?解决这个问题的最好办法就是折中,编译器理所当然的认为你构造一个结构体数据类型是用来打包一些数据成员的,而最小的数据成员需要1 个byte,编译器为每个结构体类型数据至少预留1 个byte的空间。所以,空结构体的大小就定位1个byte。

 

 

十、union关键字

union 关键字的用法与struct 的用法类似。union维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。例子如下: 

union Book

{

    char name[30];

    float price;

    int  page;

};

一个union只配置一个足够大的空间用来容纳最大长度的数据成员,以上例而言,最大 长度是char  name[30],所以Book的空间大小就是char  name[30]的大小,30个字节。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2015-04-07 18:00  我是一匹小黑马  阅读(197)  评论(0编辑  收藏  举报