const int* p 和 int* const p 的区别 以及 const 的其他用法

const int* p 中 const 修饰的是 *p

int* const p 中 const 修饰的是 p

关键是看const修饰的是什么

技巧是看const和*的相对位置

const在*左边,则指针指向的值不可改变;const在*右边,则指针本身不可改变;


比如:

const int * pOne (推荐)或者 int const * pOne;    //指向整形常量 的指针,它指向的值不能修改

int * const pTwo;    //指向整形的常量指针 ,它不能在指向别的变量,但指向(变量)的值可以修改。 

const int *const pThree(推荐)或者 int const * const pThree;  //指向整形常量 的常量指针 。它既不能再指向别的常量,指向的值也不能修改


需要注意的是:如果想像上面第二种方法定义一个不可改变的指针,则必须用下面的形式

int* const p=一个地址; (因为指针本身的值是不能被修改的所以它必须被初始化

==========华丽分割线=====================================================

以下内容转自:博客园 https://www.cnblogs.com/xkfz007/articles/2419540.html

下面说一下const的一些其他用法:

const修饰函数参数

const修饰函数参数是它最广泛的一种用途,它表示在函数体中不能修改参数的值(包括参数本身的值或者参数其中包含的值):

void function(const int Var);     //传递过来的参数在函数内不可以改变(无意义,该函数以传值的方式调用)

void function(const char* Var);   //参数指针所指内容为常量不可变

void function(char* const Var);   //参数指针本身为常量不可变(也无意义,var本身也是通过传值的形式赋值的)

void function(const Class& Var); //引用参数在函数内不可以改变

参数const通常用于参数为指针或引用的情况,若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用const修饰。

const修饰类对象/对象指针/对象引用

const修饰类对象表示该对象为常量对象,其中的任何成员都不能被修改。对于对象指针和对象引用也是一样。

const修饰的对象,该对象的任何非const成员函数都不能被调用,因为任何非const成员函数会有修改成员变量的企图。

例如:

class AAA

{    
    void func1();

    void func2() const;

}

const AAA aObj; //aObj是由const修饰的对象,所以aObj无法调用类中的非const方法

aObj.func1(); 错误

aObj.func2(); 正确

 

const AAA* aObj = new AAA();  //aObj是由const修饰的对象指针,所以aObj也无法调用类中的非const方法


aObj->func1(); 错误
aObj->func2(); 正确

const修饰数据成员 

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么,例如:

class A
{
    const int size = 100; //错误
    int array[size];       //错误,未知的size
}

const数据成员的初始化只能在类的构造函数的初始化列表中进行。要想建立在整个类中都恒定的常量,可以用类中的枚举常量来实现,例如: 

class A
{

…
  enum {size1=100, size2 = 200 };
  int array1[size1];
  int array2[size2];
…

}

枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。

const修饰成员函数 

const修饰类的成员函数,用const修饰的成员函数不能改变对象的成员变量。一般把const写在成员函数的最后:

class A

{
...

void function()const; //常成员函数, 它不改变对象的成员变量(除非有mutable修饰). 也不能调用类中任何非const成员函数。

...

} 

对于const类对象/指针/引用,只能调用类的const成员函数。 

const修饰成员函数的返回值

1、一般情况下,函数的返回值为某个对象时,如果将其声明为const时,多用于操作符的重载。通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回const对象,或返回const对象的引用,则返回值具有const属性,返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。

2、如果给采用“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针所指的内容)不能被修改,该返回值只能被赋给加const 修饰的同类型指针:

const char * GetString(void);

// 如下语句将出现编译错误:
char *str=GetString();

// 正确的用法是:
const char *str=GetString();

const常量与define宏定义的区别

(1) 编译器处理方式不同

define宏是在预处理阶段展开。

const常量是编译运行阶段使用。

(2)类型和安全检查不同

define宏没有类型,不做任何类型检查,仅仅是展开。

const常量有具体的类型,在编译阶段会执行类型检查。

(3) 存储方式不同

define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。

const常量会在内存中分配(可以是堆中也可以是栈中)。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值