[c++基础]预处理,const指针与sizeof

来源:互联网 发布:网络教育法律专业 编辑:程序博客网 时间:2024/05/03 10:44

const指针

  • const修饰指针
int b= 100;const int d;       //错误,const常量赋值时必须同时初始化const int* a= &b;  //情况1int const *a= &b;  //情况2int* const a= &b;  //情况3const int* const a= &b;  //情况4const std::vector<int>::interator iter = vec.begin();//作用像T *const, ++iter 错误:iter是const std::vector<int>::const_iterator cIter = vec.begin(); //作用像const T*,*cIter = 10 错误:*cIter是const

如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量。可以先不进行初始化,即
const int* a; //正确

如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。定义时必须同时初始化,即
int* const a; //错误
int* const a= &b; //正确

  • const char * const * keyword1
    keyword1是一个二级指针变量,这个二级指针指向一个一级指针常量(不能通过修改这个二级指针去修改一级指针中的值),这个一级指针常量指向一个字符常量(不能通过这个一级指针修改这个字符的值)
  • const char *keyword2
    keyword2是一个指针变量,指向一个只读(不可通过该指针修改)的字符
  • const char * const keyword3
    keyword3是一个指针常量,指向一个只读(不可通过该指针修改)字符
  • const char keyword4
    keyword4是一个字符常量

判断依据: 指针右结合性


  • mutable修饰为const的成员函数,就可以修改它

    这里写图片描述
    这里写图片描述

const常量与define宏定义区别

(1)编译器处理方式不同
define宏是在预处理阶段展开。const常量是编译运行阶段使用。

(2)类型和安全检查不同
define宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查。

(3)存储方式不同
define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)。

更多const具体用法见:
http://blog.csdn.net/qq_26304333/article/details/64443552

sizeof

char* ss1="0123456789";         //sizeof(ss1)= 4 (指针类型)  sizeof(*ss1)= 11 (char类型)char ss2[]= "0123456789";       //sizeof(ss2)= 11char ss3[100]= "0123456789"     //sizeof(ss3)= 100int ss4[100];                   //sizeof(ss4)= 100*4= 400int ss5[20]= {3, 4};            //sizeof(ss5)= 20*4= 80char q1[]= "abc";               //sizeof(q1)= 4char q2[]= "a\n";               //sizeof(q2)= 3 (\n算一位)char* q3= "a\n";                //sizeof(q3)= 4 (指针)char q4[2][3]= {"aa ", "bb "};  //sizeof(q4)= 6char *str1= (char *)malloc(100);//sizeof(str1)= 4 (指针)char *str2= (void *)malloc(100);//sizeof(str1)= 4 (指针)外:sizeof(string)= 4
char var[10];int test(char var[]) {    return sizeof(var);}//结果为4, 因为var[]等价于*var, 退化成一个指针
  • 结构体的sizeof

    数据对齐规则: 传送门

(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)

(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。

例子:
这里写图片描述

解法:画对齐图

这里写图片描述

  • sizeof与strlen

    (1)sizeof操作符的结果类型是size_t,它在头文件中的typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
    (2)sizeof是运算符,strlen是函数。
    (3)sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾的。sizeof还可以用函数做参数,比如:

short f();printf("%d\n", sizeof(f()));

输出的结果是sizeof(short),即2。
(4)大部分编译程序在编译的时候就把sizeof计算过了,是类型或是变量的长度。这就是sizeof(x)可以用来定义数组维数的原因:

char str[20]= "0123456789";int a= strlen(str); //a= 10int b= sizeof(str); //b= 20

内联函数和宏定义

inline一般只用于如下情况:
(1)一个函数不断被重复调用。
(2)函数只有简单的几行,且函数内不包含for、while、switch语句。
一般来说,我们写小程序没有必要定义成inline,但是如果要完成一个工程项目,当一个简单函数被调用多次时,则应该考虑用inline。

关键字inline必须与函数定义体放在一起才能使函数成为内联,仅将inline放在函数声明前面不起任何作用。

inline void Foo(int x);  //不能成为内联函数void Foo(int x) {}
  • 比较

    同:对于短小的代码来说inline增加空间消耗换来的是效率提高

    异:内联函数要做参数类型检查,这是内联函数跟宏相比的优势。inline是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到那里去。但是inline在和宏相比没有付出任何额外代价的情况下更安全。


—– From《程序员面试宝典》

0 0