了解C语言中的const

    限定符const可以应用于任何变量的声明,以指定其值不会更改(这取决于const变量存储的位置,我们可以使用指针更改const变量的值)。

1. 指向变量的指针
int *ptr;

    我们可以更改ptr的值,也可以更改ptr指向对象的值。指针和指针所指向的值都存储在读写区域中。请参见以下代码片段:

#include <stdio.h> 
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 <stdio.h>  
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 <stdio.h>  
  
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 <stdio.h> 
  
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 <stdio.h> 
   
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 <stdio.h> 
   
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’
参考文档

[1]Narendra Kangralkar.Const Qualifier in C[EB/OL].https://www.geeksforgeeks.org/const-qualifier-in-c/,2019-08-26.
[2]Karllen.C++ const 关键字小结[EB/OL].https://www.cnblogs.com/Forever-Kenlen-Ja/p/3776991.html,2014-06-08.
(const 与 * 号的位置,牢记“左定值,右定向”)
[3]cppreference.com.const type qualifier[EB/OL].https://en.cppreference.com/w/c/language/const,2020-12-15.
(const在结构体中的应用,可以参考此文)
[4]biancheng.net.C语言const的用法详解,C语言常量定义详解[EB/OL].http://c.biancheng.net/view/2041.html,2021-01-01.
(const在函数形参中的应用,可以参考此文)

猜你喜欢

转载自blog.csdn.net/zsx0728/article/details/113681103