代码改变世界

基础知识

2014-02-14 12:37  Phenix_Yu  阅读(262)  评论(1)    收藏  举报
  1.  int a[3][4];定义了一个二维数组,该二维数组第0行的地址为a,第1行的地址为a+1,第2行的地址为a+2,想从行的地址得到元素的地址,需在行地址前加上指针运算符“*”,即*a就是第0行首个元素的地址即a[0][0]的地址,而a[0][2]的地址就是在a[0][0]的地址基础上加上位移量2,即*a+2,然后想得到a[0][2]这个元素的值呢就再加上一个指针运算符“*”,即*(*a+2)
  2. 对于数组指针(pointer to array)的声明是这样:

         int (*pa)[5]:  表示声明一个指向5个元素数组的指针,与int * 类型不同,数组变量也是指针,所以pa是指针的指针
         int *pa[5]:表示申请一个5个元素的数组,元素类型是指针(int *)
         int p[5]:p是int*类型指针,pa=&p

  3. const的用法
        const int *A; //const修饰指向的对象,A可变,A指向的对象不可变
          int const *A; //const修饰指向的对象,A可变,A指向的对象不可变
          int * const A; //const修饰指针A, A不可变,A指向的对象可变
          const int *const A;//指针AA指向的对象都不可变
    4.  Static关键字的两种种用法

  • 局部静态变量    

     只初始化一次,在静态存储区分配,只能在定义该变量的函数内使用该变量,函数退出后变量仍存在但不可访问

  •  全局静态变量

     在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量,全局静态变量在声明他的文件之外是不可见的,静态函数道理相同
    5.  C语言中具体的存储类型有auto,register,static,extern,static和extern类型变量存在静态存储区,auto存在栈中,register存在寄存器中

    6.  32位系统中sizeof(指针变量)结果都返回4,sizeof(数组变量)返回数组大小,sizeof(结构体变量)则要计算填充字节的大小,空结构体sizeof返回1,字节对齐的规则与编译器有关,但一般会满足下面四个规则:

    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。 


  编译器Pack指令会影响内存对齐方式,#pragma pack(n),此时的对齐规则:

  1)数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员  的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行,即结构体成员偏移量=min(sizeof(结构中的成员,n))

  2)结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

    7. volatile关键字告诉编译器与volatile变量有关的运算,不要进行编译优化,以免出错