c***t int 和int c***t的区别(请教: c++中,c***t int a=1; 与 int c***t a=1;有什么区别)
本文目录
- 请教: c++中,c***t int a=1; 与 int c***t a=1;有什么区别
- c***t int *p和int * c***t p的区别
- 什么是c***t int c***t int和int的区别是什么
- c***t int a和int c***t a有什么区别
- c***t int和int有什么区别
- c***t int, int* c***t的区别是什么
- c++:常量,c***t int,int c***t区别
- int c***t a 和c***t int a有什么区别
- 关于c***t的问题 c***t int *a; int c***t *a; int *c***t a; 的区别
- c***t int*和int c***t*的区别
请教: c++中,c***t int a=1; 与 int c***t a=1;有什么区别
关键字:C***t,C***t函数,C***t变量,函数后面的C***t
看到c***t 关键字,C++程序员首先想到的可能是c***t 常量。这可不是良好的条件反射。如果只知道用c***t 定义常量,那么相当于把**仅用于制作鞭炮。c***t 更大的魅力是它可以修饰函数的参数、返回值,甚至函数的定义体。
c***t 是c***tant 的缩写,“恒定不变”的意思。被c***t 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。所以很多C++程序设计书籍建议:“Use c***t whenever you need”。
1.用c***t 修饰函数的参数
如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加c***t 修饰,否则该参数将失去输出功能。c***t 只能修饰输入参数:
如果输入参数采用“指针传递”,那么加c***t 修饰可以防止意外地改动该指针,起到保护作用。
例如StringCopy 函数:
void StringCopy(char *strDestination, c***t char *strSource);
其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上c***t修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。
如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加c***t 修饰。
例如不要将函数void Func1(int x) 写成void Func1(c***t int x)。同理不要将函数void Func2(A a) 写成void Func2(c***t A a)。其中A 为用户自定义的数据类型。
对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。
为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点:
“引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加c***t修饰即可,因此函数最终成为void Func(c***t A &a)。
以此类推,是否应将void Func(int x) 改写为void Func(c***t int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。
问题是如此的缠绵,我只好将“c***t &”修饰输入参数的用法总结一下。
对于非内部数据类型的输入参数,应该将“值传递”的方式改为“c***t 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(c***t A &a)。
对于内部数据类型的输入参数,不要将“值传递”的方式改为“c***t 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(c***t int &x)。
2 用c***t 修饰函数的返回值
如果给以“指针传递”方式的函数返回值加c***t 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加c***t 修饰的同类型指针。例如函数
c***t char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
c***t char *str = GetString();
如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加c***t 修饰没有任何价值。
例如不要把函数int GetInt(void) 写成c***t int GetInt(void)。
同理不要把函数A GetA(void) 写成c***t A GetA(void),其中A 为用户自定义的数据类型。
如果返回值不是内部数据类型,将函数A GetA(void) 改写为c***t A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。
例如:
class A
{
A & operate = (c***t A &other); // 赋值函数
};
A a, b, c; // a, b, c 为A 的对象
a = b = c; // 正常的链式赋值
(a = b) = c; // 不正常的链式赋值,但合法
如果将赋值函数的返回值加c***t 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。
3 c***t 成员函数
任何不会修改数据成员的函数都应该声明为c***t 类型。如果在编写c***t 成员函数时,不慎修改了数据成员,或者调用了其它非c***t 成员函数,编译器将指出错误,这无疑会提高程序的健壮性。以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为c***t 函数。编译器将指出GetCount 函数中的错误。
class Stack
{
public:
void Push(int elem);
int Pop(void);
int GetCount(void) c***t; // c***t 成员函数
private:
int m_num;
int m_data;
};
int Stack::GetCount(void) c***t
{
++ m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非c***t 函数
return m_num;
}
c***t 成员函数的声明看起来怪怪的:c***t 关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。
关于C***t函数的几点规则:
a. c***t对象只能访问c***t成员函数,而非c***t对象可以访问任意的成员函数,包括c***t成员函数.
b. c***t对象的成员是不可修改的,然而c***t对象通过指针维护的对象却是可以修改的.
c. c***t成员函数不可以修改对象的数据,不管对象是否具有c***t性质.它在编译时,以是否修改成员数据为依据,进行检查.
e. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的c***t成员函数是可以修改它的
暂无留言!
***隐藏网址***
c***t int *p和int * c***t p的区别
c***t int *p和int * c***t p的区别如下:
c***t int *p表明指向的对象是c***t型,不可以修改,但是指针p的指向可以修改。
* c***t p表明指针变量p是c***t型,它的指向不可修改,但是指向的对象可以修改。
一般来说用*限定的是指针区域存放的内容,不用*的是内存地址。
什么是c***t int c***t int和int的区别是什么
一、c***t int 和int 的区别
1、返回值
c***t int & 是返回这个数值的一个常量的引用。
而int 是返回这个数值的一个拷贝。
int 是进行拷贝构造,而c***t int & 是返回的引用。拷贝构造更消耗时间,与此同时还用析构函数。因为产生了一个拷贝,你就可以轻易地修改拷贝的内容。
2、取指针
c***t int类型一旦定义以后就不能修改,int类型是随时可以修改的。
在取指针方面,c***t有略复杂的东西,但是常规的、合理的操作不应该涉及到,因为c***t int是用来保存一些全局常量的,这些常量在编译期可以改,在运行期不能改。
听起来这像宏,其实这确实就是用来取代宏的: #define PI 3.14 c***t float Pi = 3.14; 如果你的代码里用到了100次PI(宏),你的代码中会保存100个3.14这个常数。
鉴于使用常数进行运算的机器代码很多时候会比使用变量来的长,如果你换用100次Pi(c***t float),程序编译后的机器码里就不需要出现100次常量3.14,只要在需要的时候引用存有3.14的常量就行了。
特别在复杂的运算里,3.14这个常量(其实是无法修改的变量)会被一直装载在寄存器里带来一些性能提升。
3、内容
c***tint* p; //p可变,p指向的内容不可变,int c***t* p; //p可变,p指向的内容不可变。 int* c***t p; //p不可变,p指向的内容可变 c***t int* c***t p; //p和p指向的内容都不可变。
二、c***t的作用:
1、可以定义c***t常量,具有不可变性。
例如:c***t int Max=100; Max++会产生错误;
2、便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
例如: void f(c***t int i) { .........} 编译器就会知道i是一个常量,不允许修改;
3、可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!
如1中,如果想修改Max的内容,只需要它修改成:c***t int Max=you want;即可!
4、可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错;
例如: void f(c***t int i) { i=10;//error! }
5、可以节省空间,避免不必要的内存分配。
扩展资料
当c***t修饰的是指针类型,那么指针的值就不能改变,即不能指向其他地址,但是可以通过指针修改其指向地址里面的值。
当c***t修饰时指针指向的类型时候,那么指针被指向其他地址,但是不能通过指针修改指针里面的值。
1)先从c***t int i说起。
使用c***t修饰的i我们称之为符号常量。即,i不能在其他地方被重新赋值了。注意:c***t int i与int c***t i是等价的,相同的,即c***t与int的位置无所谓。
2)c***t int *p
看例子:
int i1=30;
int i2=40;
c***t int *p=&i1;
p=&i2; //此处,p可以在任何时候重新赋值一个新的内存地址。
i2=80; //这里能用*p=80来代替吗?答案是不能
printf("%d",*p); //输出80
分析:p的值是可以被修改的,即它可以重新指向另一个地址。但是不能通过*p来修改i2的值。
首先,c***t修饰的是整个*p(注意,是*p而不是p),所以*p是常量,是不能被赋值的。虽然p所指的i2是变量而不是常量;
其次,p前并没有用c***t修饰,所以p是指针变量。能被赋值重新指向另一个内存地址。
参考资料:百度百科——c***t
c***t int a和int c***t a有什么区别
没有区别的,都是表示不可改变数值的int常量。而c***t
在定义指针时,c***t
int
*a和int
c***t
*a才有区别。c***t
int
*a
表示a只能只想常量的int;int
*c***t
a
表示a是一个常指针,只能指向某一固定的int变量。
c***t int和int有什么区别
一、区别如下:
1、int定义的量是变量,它的值可以更改;而c***t int 定义的是一个常量,它的值不可以更改。
2、int在定义的时候,不需要初始化,而c***t int 在定义的时候必须初始化;
二、c***t的作用:把对象转换成一个常量
拓展资料
c***t与define。两者都可以用来定义常量,但是c***t定义时,定义了常量的类型,所以更精确一些。#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似内联函数(Inline)。c***t和define定义的常量可以放在头文件里面。
c***t int, int* c***t的区别是什么
1、内容不同
c***tint* p; //p可变,p指向的内容不可变,int c***t* p; //p可变,p指向的内容不可变。 int* c***t p; //p不可变,p指向的内容可变 c***t int* c***t p; //p和p指向的内容都不可变。
2、取指针
c***t int类型一旦定义以后就不能修改,int类型是随时可以修改的。
3、返回值
c***t int是返回这个数值的一个常量的引用。
而int是返回这个数值的一个拷贝。
c***t作用:
1、可以定义c***t常量,具有不可变性。
例如:c***t int Max=100; Max++会产生错误。
2、便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。
例如: void f(c***t int i) { .........} 编译器就会知道i是一个常量,不允许修改。
3、可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
扩展资料:
c***t 和指针一起使用会有几种不同的顺序,如下所示:
1、c***t int *p1;
2、int c***t *p2;
3、int * c***t p3;
在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。
当然,指针本身和它指向的数据都有可能是只读的,下面的两种写法能够做到这一点:
1、c***t int * c***t p4;
2、int c***t * c***t p5;
c++:常量,c***t int,int c***t区别
这个是符合C++ 的语法规则的。这里的c***t限定的都是整型变量。你在判断的时候把那个变量类型去掉,就可以看出c***t是限定谁的。
比如你看 (1) c***t int *p;和 (2) int * c***t p; 中c***t修饰的常量就不一样,(1)中去掉int变为
c***t *p ,(2)中去掉int * 变为 c***t p,这时你会发现c***t修饰的明显是不同的变量,c***t *p表示*p的数值为常量但p的值(地址)不是常量,c***t p 则表示p的值是常量。
int c***t a 和c***t int a有什么区别
没有区别。
修饰非指针时,没有区别:都是声明int常量a;修饰指针时,置于int前,表示指针只能指向常量,*a赋值非法,置于int后,表示指针常量,a赋值非法
关于c***t的问题 c***t int *a; int c***t *a; int *c***t a; 的区别
1、如果c***t位于星号的左侧,则c***t就是用来修饰指针所指向的变量,即指针指向为常量;如果c***t位于星号的右侧,c***t就是修饰指针本身,即指针本身是常量。
2、因此,c***t int *a;和 int c***t *a;的情况相同,都是指针所指向的内容为常量(c***t放在变量声明符的位置无关),这种情况下不允许对内容进行更改操作,如不能*a = 3 ; ,int *c***t a;为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的。
3、c***t int* c***t a;为指针本身和指向的内容均为常量。
c***t int*和int c***t*的区别
这应该没区别
指针的话有区别
引用以下:
对指针来说,可以指定指针本身为c***t,也可以指定指针所指的数据为c***t,或二者同时指定为c***t。
A c***t int* a; 或int c***t *a;//*a是c***t,但指针a可变
B c***t* int a;或int * c***t a;//a是c***t,但*a可变
C (c***t int* c***t a;等价于int * c***t a c***t;)或int c***t* c***t a;//a和*a都是c***t,常量和指针的值都不能改变
更多文章:
js点击图片弹出大图(求JavaScript图片代码,点击图片后,出现图片的大图,背景变黑色)
2026年4月11日 04:20
illustrated by(writtenby和illustratedby的区别)
2026年4月11日 04:00
apprehensive(apprehensive词根词缀是什么)
2026年4月11日 03:20
系统分页怎么实现的(分页机制是由操作系统实现的仅仅对应用层的进程有作用 还是分页机制对操作系统本身的代码也有作用)
2026年4月11日 02:00





