const关键字的最全用法
请细细品读,才能解决概念
有错误请友好评论指出,查阅后会改正,谢谢。觉得可以,请随便评论些啥支持小黑子我,为各位输出更多好文章和知识点。
C语言中const关键字的用法
前言
本文介绍了const关键字的用法。
编译环境:win64、vscode、mingw-64库
一、简单介绍一下:C语言中的const是什么?
在 C 语言中,关键字(也称为保留字)是一组具有特殊含义的标识符,它们被编程语言的语法所保留,用于定义语言的结构和命令。
关键字不能用作变量名、函数名或其他标识符的名字,因为它们已经被语言本身使用了。
常见的关键字有:static 、 sizeof 、 return 、 volatile 、 break 、 const 等
而其中的const(翻译:常数,恒量)关键字用于声明常量或指定变量的一部分为常量,它告诉编译器和程序员 该变量或对象的值不应该被更改
。
初始化:声明 const 变量时 必须
立即初始化。
不可修改:一旦初始化,const 变量的值就不能再被改变。
作用域:const 变量的作用域与普通变量相同,取决于它在哪里被声明
安全性和性能:提高程序的健壮性,同时也可能带来一些运行性能上的好处,因为编译器可以进行更多的优化。
二、使用场景
1.修饰变量
修饰之后成为常量
const double PI = 3.1415926; // 声明一个双精度变量为常量
const int ikun_year = 78840000; // 声明一个整型变量为常量
使用 const 关键字修饰两个变量成为常量并声明,且这两个常量已经被初始化,在程序运行期间其值不能被改变
#include <stdio.h>
int main()
{
const double PI = 3.1415926; // 声明一个双精度整型常量
const int ikun_year = 78840000; // 声明一个整型常量
// 下面的两行代码均会导致编译错误
ikun_year = 3;
PI = 1.2345678;
return 0;
}
修饰变量之后变成常量,另外一种定义常量的方法是使用预处理器宏
例: #defien PI 3.1415926
2.修饰 指针
修饰之后成为 常量指针:指向常量的指针
const int *p = &var; int const *p; //两个相同意思
声明了一个指向 被const的整型变量var 的指针 p
把(int *p)看成 变量var的地址, 变量var地址被const了,所以var地址里面的东西不能变,所以var变量成为var常量了,然后这个指针p变成了指向常量var的指针,所以叫常量指针。
通过该指针 p 不能修改 var 的数据,但是可以更改p的指向。
#include <stdio.h>
int main() {
int var = 10;
int var2 = 20;
// 使用 const 修饰指针所指向的数据
const int *p = &var; // p 指向的数据是被const了
// 下面的代码会导致编译错误
*p = 20; // --错误---:尝试修改 const 对象。
// 下面的代码是正确的
p = &var2; // 正确:可以重新赋值 p 指向新的地址
printf("Value: %d\n",*p);
return 0;
}
如果删除*p = 20; ,输出
Value: 20
const int *p 也叫做指向常量(Constant Pointer)的指针。
常用场景:const char *arr[] = {“ikun”, “zhen”, “ai”, “fen”};
定义一些常见字符串数组用来做验证 、标识 、统一管理字段等。
函数使用:在函数参数
中使用这样的指针可以 确保传递给函数的数据不会被 函数内部
不小心修改
,比如在函数中涉及到内存操作、数组操作等。
例:
void func(const char *p)
{
p[1]='z';// --错误---:尝试修改 const 对象。
printf("Value: %s\n",p);
}
int main()
{
char arr[] = "ikun zhen ai fen";
func(arr);
return 0;
}
如果删除函数中的const,输出
Value: izun zhen ai fen
修饰之后成为 指针常量:一个常量类型的指针
int *const p = &var;
声明了一个指向 整型变量var 的被const的指针 p
就是p被const了,p成为了“常量",p里面保存的地址不能变
这意味着指针 p 不能修改指向,但是可以更改p指向的变量var的值.
#include <stdio.h>
int main()
{
int var = 10;
int nullptr = 20;
int *const p = &var; // p 不能被重新赋值
p = nullptr; // 错误,p const 了
*p = 20; // 正确,*p 没有 const
printf("Value: %d\n", *p);
return 0;
}
删除 p = nullptr; 则输出
Value:20
函数使用: 在函数参数中使用这样的指针可以确保传递给函数的指针不会被函数内部重新指向。
void func(int *const arr);
3.修饰 指针 和 变量(结合2)
修饰之后成为 指向常量的指针常量:一个指向常量的指针常量
const int *const p = &var;
声明了一个指向 被const的整型变量var 的被const的指针 p
就是p被const了,p成为了“常量",p里面保存的地址不能变,这意味着指针 p 不能修改指向
然后 (int *const p)也被const 了,相当于变量var地址也被const了,所以var地址里面的东西不能变
变量var的值和指针的指向都不能修改。
#include <stdio.h>
int main() {
int var = 20; // 定义一个整型变量 var,并给它赋值为 20
int var2 = 10;
const int * const p = &var; // 声明一个指向 const int 的 const 指针 p,并让它指向 var 的地址
p = &var2; // 错误,因为 p 不能重新指向其他地址
*p = 30; // 错误,因为 p 指向的数据是 const 的
printf("value: %d\n", *p);
return 0;
}
删除 p = &var; *p = 10;,则输出
Value:20
函数使用: 在函数参数中使用这样的指针,你只能读取指针的数据,不能做修改,也就是只读数据
4.特别注意:修饰 函数
const char *func();
声明了一个 被cosnt的函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *func()
{
char *arr = strdup("ikun zhen ai fen"); // 使用 strdup 动态分配内存
return arr;
}
int main()
{
//const char *p = func(); // 原本应该这么写。
char *p = (char *)func(); //使用 (char *)转换后依旧能更改,哪怕你使用const char const *func(),依旧强转之后能改。
p[1] = 'q';
printf("Value: %s\n", p);
free((char *)p);
return 0;
}
输出
Value:iqun zhen ai fen // ikun 的 k 变为了 q
注意:修饰函数,使用const char*接收了函数的返回值地址,但是你使用(char *)显式 强转 依旧能改变地址中的值
这一块地方,我的理解是:本来应该是 函数的返回值被const,返回值相当于成为了常量,然后弄个相同的数据类型接收一下返回值,返回值不能被修改才对,但是强转之后居然还能改,很疑惑。
目前这一段的理解还不够透彻。各位可以测试之后,在评论区发表自己的理解。
总结 (想简单了解作用的跳到这里)
1、const 修饰变量 为常量
const double PI = 3.1415926;
程序运行期间其值不能被改变
2、const 修饰指针
常量指针
const int *p = &var; int const *p;
通过该指针 p 不能修改 var 的数据
指针常量
int *const p = &var;
指针 p 的指向不能修改
指针和常量都修饰
const int *const p = &var;
通过该指针 p 不能修改 var 的数据,指针 p 的指向也不能修改