限定符const可以应用于任何变量的声明,以指定其值不会更改(这取决于const变量的存储位置,我们可以使用指针更改const变量的值)。如果尝试更改const,则结果是实现定义的。
1)指向变量的指针。
int *ptr;
我们可以更改ptr的值,也可以更改指向对象ptr的值。指针和指针所指向的值都存储在读写区域中。请参见以下代码片段。
#include
int main(void)
{
int i = 10;
int j = 20;
int *ptr = &i;
/* pointer to integer */
printf("*ptr: %d\n", *ptr);
/* pointer is pointing to another variable */
ptr = &j;
printf("*ptr: %d\n", *ptr);
/* we can change value stored by pointer */
*ptr = 100;
printf("*ptr: %d\n", *ptr);
return 0;
}
输出:
*ptr: 10
*ptr: 20
*ptr: 100
2)指向常量的指针。
指向常量的指针可以通过以下两种方式声明。
const int *ptr;
或者
int const *ptr;
我们可以更改指针以指向任何其他整数变量,但是不能更改使用指针ptr指向的对象(实体)的值。指针存储在读写区域(当前为堆栈)中。指向的对象可能在只读或读写区域中。让我们看下面的例子。
#include
int main(void)
{
int i = 10;
int j = 20;
/* ptr is pointer to constant */
const int *ptr = &i;
printf("ptr: %d\n", *ptr);
/* error: object pointed cannot be modified
using the pointer ptr */
*ptr = 100;
ptr = &j; /* valid */
printf("ptr: %d\n", *ptr);
return 0;
}
输出:
error: assignment of read-only location ‘*ptr’
以下是变量i本身为常数的另一个示例。
#include
int main(void)
{
/* i is stored in read only area*/
int const i = 10;
int j = 20;
/* pointer to integer constant. Here i
is of type "const int", and &i is of
type "const int *". And p is of type
"const int", types are matching no issue */
int const *ptr = &i;
printf("ptr: %d\n", *ptr);
/* error */
*ptr = 100;
/* valid. We call it up qualification. In
C/C++, the type of "int *" is allowed to up
qualify to the type "const int *". The type of
&j is "int *" and is implicitly up qualified by
the compiler to "const int *" */
ptr = &j;
printf("ptr: %d\n", *ptr);
return 0;
}
输出:
error: assignment of read-only location ‘*ptr’
C++中不允许使用降级资格,并且可能在C语言中引起警告。以下是降级资格的另一个示例。
#include
int main(void)
{
int i = 10;
int const j = 20;
/* ptr is pointing an integer object */
int *ptr = &i;
printf("*ptr: %d\n", *ptr);
/* The below assignment is invalid in C++, results in error
In C, the compiler *may* throw a warning, but casting is
implicitly allowed */
ptr = &j;
/* In C++, it is called 'down qualification'. The type of expression
&j is "const int *" and the type of ptr is "int *". The
assignment "ptr = &j" causes to implicitly remove const-ness
from the expression &j. C++ being more type restrictive, will not
allow implicit down qualification. However, C++ allows implicit
up qualification. The reason being, const qualified identifiers
are bound to be placed in read-only memory (but not always). If
C++ allows above kind of assignment (ptr = &j), we can use 'ptr'
to modify value of j which is in read-only memory. The
consequences are implementation dependent, the program may fail
at runtime. So strict type checking helps clean code. */
printf("*ptr: %d\n", *ptr);
return 0;
}
// Reference:
// http://www.dansaks.com/articles/1999-02%20const%20T%20vs%20T%20const.pdf
// More interesting stuff on C/C++ @ http://www.dansaks.com/articles.shtml
3)常数变量的指针。
int *const ptr;
上面的声明是一个指向整数变量的常量指针,这意味着我们可以更改指针所指向的对象的值,但不能将指针更改为指向另一个变量。
#include
int main(void)
{
int i = 10;
int j = 20;
/* constant pointer to integer */
int *const ptr = &i;
printf("ptr: %d\n", *ptr);
*ptr = 100; /* valid */
printf("ptr: %d\n", *ptr);
ptr = &j; /* error */
return 0;
}
输出:
error: assignment of read-only variable ‘ptr’
4)常量指向常量
const int *const ptr;
上面的声明是指向常量变量的常量指针,这意味着我们不能更改指针所指向的值,也不能将指针指向其他变量。让我们看一个例子。
#include
int main(void)
{
int i = 10;
int j = 20;
/* constant pointer to constant integer */
const int *const ptr = &i;
printf("ptr: %d\n", *ptr);
ptr = &j; /* error */
*ptr = 100; /* error */
return 0;
}
输出:
error: assignment of read-only variable ‘ptr’
error: assignment of read-only location ‘*ptr’
想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。