常量保护通过指针传递给函数的变量是什么意思?
例如 :
int f ( const int vec[]);
以下命令不合法:
vec[i] = exp;
const
保护它的左侧,除非它的左侧没有任何东西,然后只有这样它才能保护它的右侧。在这种情况下,它保护vec
.
这些示例应该可以帮助您理解这一点:
指向 const 变量的指针:
int vec[] = {1,2,3};
int const *ptr = vec;
ptr[1] = SOMETHING; //ERROR :(
一个指向变量的 const 指针:
int vec[] = {1,2,3};
int* const ptr = vec;
ptr[1] = SOMETHING; //OK :)
ptr = NULL; //ERROR :(
这些图像应该可以帮助您更好地理解这一点:
const 是编译器强制执行的限定符。什么
const int vec[];
意思是你不能修改 vec 中包含的整数。
注意:这并不意味着内存不可修改。人们倾向于将 const 误认为是保护那部分内存的运行时保证……事实并非如此。这只是 c 编译器强制执行的东西,以试图保护程序员不做愚蠢的事情。
编辑:与函数调用有关的 const 最明显的用途是当您想通过引用传递事物时,因为它们很大并且复制它们会很昂贵。但是你要保证函数不会修改它们。
int someFunction(const int ¬Changeable, int &modifiable);
在上面的声明中,可修改的整数可以由 someFunction 更改,并且由于它是通过引用传递的,因此调用例程也会更改。不应修改 notChangeable int。
下面是一些你可以用 const 和指针做的讨厌的事情的例子。由于人们在谈论修改内存,并且只是作为编译时间保证,我想我会演示这对你意味着什么。
#include <iostream>
#include <cstring>
using namespace std;
int main() {
const int* intOne = new int(10);
int* intTwo = new int(20);//Toggle these two lines
//int* const intTWo = new int(20);//Toggle these two lines
cout << *intOne << " " << *intTwo << endl;
intTwo -= sizeof(int); //Let's move our pointer back one integer!
*intTwo = 50000;//Now let's change that integer
cout << intOne << " " << intTwo << endl;//INteresting our pointers point to the same memory now
cout << *intOne << " " << *intTwo << endl;//And we were able to modify *intOne... even though it was const.
}
另请注意,我们已经泄露了 intTwo 指向的内容,尽管我们知道如何找回它,所以这并不可怕。而且,如果您想了解使指针保持不变和它指向不变的事物之间的区别,您可以切换我评论的两行。
预期输出:
10 20
0x1061009e0 0x1061009e0
50000 50000
它是一个修饰符,确保您不直接修改变量值。它不能保护您不以其他方式修改内存,例如通过指针。当您知道自己不想改变某些东西但又不好依赖时,使用它是件好事。
其他人已经说过,const *
您声明中显示的参数告诉编译器指向的数据操作系统是只读的。我想给出更高层次的解释,说明为什么要以这种方式声明函数的参数。该声明背后的想法是告诉应用程序的读者,您的函数不会修改您传递给它的数据。
这是你的界面做出的承诺,告诉它不会有意想不到的副作用。
相反,没有 const 声明很明显缓冲区可能会被更改。
这也是为什么传递const *
给只需要一个简单 * 的函数会产生警告但反之不会产生警告的原因。
示例:strlen
声明为size_t strlen (const char *s)
从中我可以推断出我可以调用它而不会有修改我的数据的危险。
strtok
从中声明char *strtok (char *s, const char *delim)
我认为我传递的缓冲区已被修改并且必须小心。
TL;DR const 添加有关函数属性的信息。
该声明可以读作“一个int
常量数组”或“一个值不能更改的整数数组”。这就是该命令不合法的原因:它会改变其中一个整数的值。
当某个变量const
在参数列表中声明时,该变量不能在函数体中修改。编译器将捕获任何这样做的尝试。换句话说,声明为的变量const
不是合法的左值。
它使函数内部的代码不会因为编译器出错而意外修改传递对象的数据。
数组是通过引用它们的基地址来传递的。对于像变量这样的普通原语,情况并非如此int
,如果传递了一个整数,则会在函数的范围内创建一个带有传递值的局部变量,如果进行了更改,则它们仅取决于局部变量。但是由于数组不是这种情况,因此您可能会不小心修改array[i]=2
. 但是,如果用const
限定符声明,则可以防止这种情况。这就是关键字的性质。
这就是为什么许多人使用该原型,尤其是库编写者。因为,图书馆被大量用户使用。函数中的一个错误,由于意外写入可以玩用户的堆栈...
当然,但这可能无法阻止蓄意攻击,因为它只需要编译时间,并且可以轻松解决此问题。