编程珠玑之关键字(1)--《c语言深度剖析》整理(转)

一、最快关键字register

关键字regiter请求编译器尽可能的将变量存在CPU的寄存器中。有几点注意的地方。

1、register变量必须是能被CPU寄存器所接受的类型,这通常意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度。

    但是,有些机器的寄存器也能存放浮点数。

2、register变量可能不存放在内存中,所以不能用取址符运算符“ & ”。

3、只有局部变量和形参可以作为register变量,全局变量不行。

4、静态变量不能定义为register。

 总结:寄存器变量不是越多越好,当寄存器变量的个数超过寄存器的数目的时候,寄存变量也就退化为放到内存中。因此寄存器变量应用较少。

二、static作用

1. 修饰变量

  (1) 限定变量的作用域: (存放于文件的静态区中)

本文件中:

静态全局变量:作用域从变量定义开始处到文件结束(本文中在定义之前引用此变量也要加extern)

静态局部变量:作用域限于定义的函数中

工程文件中: 仅限本文件中,其他的文件的不能引用此变量

 (2) 生命周期:

从程序启动直至程序结束。

2. 修饰函数

限定函数的作用域为本文件中,其他的文件不能引用此函数

三、最容易混淆的关键字sizeof(本人之前一直以为sizeof是函数 惭愧)

事实证明 sizeof是关键字,如下:

int i=0;
       A),sizeof(int); B),sizeof(i); C),sizeof  int; D),sizeof  i;

此处四种用法第三种是错误的 ,由此可见sizeof 是关键字

关于sizeof的 一些用法习题:

int *p = NULL;
   sizeof(p)——
   sizeof(*p)——
   int a[100];
   sizeof (a) ——
   sizeof(a[100])——
   sizeof(&a)——
   sizeof(&a[0])——
   int b[100];
   void fun(int b[100])
   {
        sizeof(b);// sizeof (b) ——
   }

 答案: 4   4   400  4   4  4  4

四、 bool, float , 指针类型与零值的比较

1. bool类型的值与0比较

A), if(bTestFlag == 0); if(bTestFlag == 1);
   B), if(bTestFlag == TRUE); if(bTestFlag == FLASE);
   C), if(bTestFlag); if(!bTestFlag);

解析:

A :可读性比较差,不知道bTestFlag变量的类型,误以为是整形

B:不同的编译器,true值的定义不同:Visual C++定义为1,而Visual Basic 就把TRUE 定义为-1

   C:规范 编译器中0 为false 非零为true

2. float 与 0 比较

float fTestVal = 0.0;
      A), if(fTestVal == 0.0); if(fTestVal != 0.0);
      B), if((fTestVal >= -EPSINON) && (fTestVal <= EPSINON)); //EPSINON 为定义好的精度。

  解析:float 在计算机存储有精度限制,与0,与具体的浮点数直接比较都是不准确的,所以B的定义较好。[0.0-EPSINON,0.0+EPSINON] 当然EPSINON范围不能过大

3. 指针变量与0 比较

int* p = NULL;//定义指针一定要同时初始化,指针与数组那章会详细讲解。
    A), if(p == 0); if(p != 0);
    B), if(p); if(!p);
    C) , if(NULL == p); if(NULL != p);
   解析:A  容易和int 类型的想混淆;B 容易和bool类型想混淆(可读性比较差)

五、c语言中的空语句的写法

1)  ;

2) NULL;

六、switch 关键字

switch关键字使用注意事项:

1) case 后面变量: 整形或字符型或者常量表达式(可以跟const类型修饰的变量,比如const int KEY = 1)

2) 每个case 后面必须接break ,除非集中case的叠加(但case 后面绝对不可以跟continue,continue 用于循环中)

3) deflaut 后面应用于异常情况的处理,不应将自己的case 最后一种情况介于default 之后,降低程序的容错性

七、const 修饰只读变量

1.  const 修饰的变量 是只读的,变量的值不可以改变,变量存在于符号表中,没有了存储与读内存的操作;

#define M 3 //宏常量
const int N=5; //此时并未将N 放入内存中
......
int i=N; //此时为N 分配内存,以后不再分配!
int I=M; //预编译期间进行宏替换,分配内存
int j=N; //没有内存分配
int J=M; //再进行宏替换,又一次分配内存!

2.  const 修饰的变量定义的时候必须初始化

3、const 修饰的变量是编译器变量,define 定义的变量是预编译期变量

4、const 修饰的变量和define修饰的变量的区别

(1)const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数

(2)const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。

(3)#define 宏是在预编译阶段进行替换,而const 修饰的只读变量是在编译的时候确定其值

(4)#define 宏没有类型,而const 修饰的只读变量具有特定的类型。

5. const 修饰指针

const int *p; // p 可变,p 指向的对象不可变
      int const *p; // p 可变,p 指向的对象不可变
      int *const p; // p 不可变,p 指向的对象可变
      const int *const p; //指针p 和p 指向的对象都不可变

八、最异变的关键字volatile

volatile 修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优     化,从而可以提供对特殊地址的稳定访问;

九、struct

1、空结构体的大小

struct A

{

}aa;

sizeof(aa)  结果等于 1

2. 柔性数组

typedef struct A

{
            int i;
            int a[];
      }aa;

sizeof(aa) 等于 4,可见结构的体中的柔性数组的大小是0,不占结构体的空间,仿佛不是结构的体得一部分;

十、union

存储模式:大端模式和小端模式。
    大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
    小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

    union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存  取都是从union 的首地址位置开始

1. 枚举类型所占空间大小

enum Color
    {
           GREEN = 1,
           RED,
           BLUE,
           GREEN_RED = 10,
           GREEN_BLUE
    }ColorVal;

sizeof(ColorVal)等于4

2. 枚举与#define 宏的区别

1),#define 宏常量是在预编译阶段进行简单替换。枚举常量则是在编译的时候确定其值。
    2),一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
    3),枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

3. 用函数确定系统的大小端模式

[cpp] view plaincopyprint?

    1. int checkSystem( )
    2. {
    3. union check
    4. {
    5. int i;
    6. char ch;
    7. } c;
    8. c.i = 1;
    9. return (c.ch ==1);
    10. }

编程珠玑之关键字(1)--《c语言深度剖析》整理(转)

时间: 2024-10-31 04:03:41

编程珠玑之关键字(1)--《c语言深度剖析》整理(转)的相关文章

读书笔记之:C语言深度剖析

读书笔记之:C语言深度剖析 <C 语言深度解剖>这本书是一本“解开程序员面试笔试的秘密”的好书.作者陈正冲老师提出“以含金量勇敢挑战国内外同类书籍”,确实,这本书中的知识点都是一些在面试中常见的考点,并且很多都是我们平常不注意的点,对于我们深入理解C语言确实很有帮助. 第1章关键字 1.register虽然寄存器的速度非常快,但是使用register修饰符也有些限制的:register变量必须是能被CPU寄存器所接受的类型.意味着register变量必须是一个单个的值,并且其长度应小于或等于整

[ 1011] &lt;&lt;C语言深度剖析&gt;&gt; 测试 TEST

/******************************** **  wzsts<C语言深度剖析>2016 ** **                    ** **     fun1~fun6代表6章节内容 ** **fun10~fun19代表fun1所调用函数 ** **                    ** **     世界因规则而美好     ** ** #if(1)可运行,#if(0)不运行. ** ** Data  Author   PC       ** **16

《C语言深度剖析》笔记

关键字: C语言关键字32个: 关键字                                         意 义 auto                           声明自动变量,缺省时编译器一般默认为 auto int                               声明整型变量 double                       声明双精度变量 long                            声明长整型变量 char         

C语言深度剖析学习错误点记录

0. static修饰变量和函数 static修饰变量,1)限定作用域,本文件内.全局变量(自定义起,本文件前面要用需extern声明),局部变量函数内:2)生命周期,程序运行期间一直保存. static修饰函数,限定作用域,本文件内.1. enum类型变量大小为4(sizeof),不论enum成员数量.2. enum成员间用","分割,最后一个成员后可不加分隔号. 而struct.union成员间用":"分割,最后一个成员后要加分隔号.而struct的成员初始化用

C语言深度剖析——读书笔记

1. 什么是定义,什么是声明? 定义:编译器创建一个对象,并为这个对象分配一块内存,给它取上一个名字. 声明:1>告诉编译器这个名字已经已经分配到一块内存上了 2>告诉编译器这个名字已经被预定了,别的地方不能再用它来作为变量名或对象名. 2. auto: 在缺省的情况下,编译器默认所有的变量都是auto的, 3. register: register变量必须是单个的值,并且其长度应该小于或等于整形的长度,而且register变量可能不存放在内存中,所以不能用&--取地址符来获取regi

C语言深度剖析自测题8解析

#include <stdio.h> int  main(void) {    int  a[5] = {1, 2, 3, 4, 5}; int* ptr1 = (int*)(&a + 1); int* ptr2 = (int*)((int)a + 1); printf("%x, %x\n", ptr1[-1], *ptr2); } 这个题目主要是考了两个知识点一个是指针的知识,第二个是大端机和小端机的知识 首先需要明确x86是小端机,所以它的数值在各个字节中的顺序

C语言深度剖析 -- 第一课 基本数据类型

第一课 -- 基本数据类型分析 任何编程语言,它都要操作存在内存中的数据, 变量的本质是内存中一段数据空间的别名 1 #include <stdlib.h> 2 #include <stdio.h> 3 4 //自定义一些数据类型 5 typedef int INT32; 6 typedef unsigned char BYTE; 7 8 typedef struct _demo 9 { 10 short s; 11 BYTE b1; 12 BYTE b2; 13 INT32 i;

编程珠玑番外篇之番外篇-O 中间语言和虚拟机漫谈(ZZ)

http://blog.youxu.info/2014/05/11/language-and-vm/ 导言 编程语言的发展历史,总的来说,是一个从抽象机器操作逐步进化为抽象人的思维的过程.机器操作和人的思维如一枚硬币的两面,而语言编译器就像是个双面胶,将这两面粘在一起,保证编程语言源程序和机器代码在行为上等价.当然,人本身并不是一个完美的编译器,不能无错的将思维表达为高级语言程序,这种偏差,即Bug.因为编译器的帮助,我们可以脱离机器细节,只关心表达思维和程序行为这一面. 编程语言的发展日新月异

编程珠玑番外篇

1.Plan 9 的八卦 在 Windows 下喜欢用 FTP 的同学抱怨 Linux 下面没有如 LeapFTP 那样的方便的工具. 在苹果下面用惯了 Cyberduck 的同学可能也会抱怨 Linux 下面使用 FTP 和 SFTP 是一件麻烦的事情. 其实一点都不麻烦, 因为在 LINUX 系统上压根就不需要用 FTP. 为什么呢? 因为一行简单的配置之后, 你就可以像使用本机文件一样使用远程的任何文件. 无论是想编辑, 查看还是删除重命名, 都和本机文件一样的用. 这么神奇的功能到底如何