const基础知识(用法、含义、好处、扩展)
int main(){
const int a; //
int const b;
const char *c;
char * const d; char buf[100]
const char *const e ;
return 0;
}
含义:
- 第一个第二个意思一样代表一个常整形数 通过指针可以修改
- 第三个 c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
- 第四个 d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
- 第五个 e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)
记忆方法
const
离变量名近
就是用来 修饰指针变量
离 变量名 远
就是用来 修饰指针指向的数据
- 如果
近的和远的 都有
,那么就同时 修饰 指针变量 以及它 指向的数据
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 所指向的内存数据不能被修改,但是本身可以修改
void getmem201(const char *p)
{
p = 1;
p = 3;
// p[1] = 'a'; // 错误内存数据不可以修改,但本身可以修改 表达式是必须可修改的左值
return;
}
// 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
void getmem202(char *const p)
{
// p = 250; // 错误本身是不可以修改的 表达式是必须可修改的左值
p[1] = 'a';
return;
}
// 指针和它所指向的内存空间,均不能被修改
void getmen203(const char *const p)
{
//p = 1;
//p = 3;
//p[1] = a;
printf("%c", p[1]);
return;
}
//结论C语言中的const修饰的变量 是假的 C语言中的const 是一个冒牌货
void constint()
{
const int a = 10;
//a = 11; error
{
int *p = &a;
*p = 100;
printf("a:%d\n", a);//a:100
}
}
int main()
{
char *p1 = NULL;
const char *p2 = NULL;
constint();
system("pause");
return 0;
}
Const好处 合理的利用const
- 指针做函数参数,可以有效的提高代码可读性,减少bug;
- 清楚的分清参数的输入和输出特性
const和指针
//const int getNum() { return 100; }
void constBae() {
int n = 90;
const int MaxNum1 = getNum(); //运行时初始化
const int MaxNum2 = n; //运行时初始化
const int MaxNum3 = 80; //编译时初始化
//MaxNum2 = 200;错误 创建后就不能再修改了
printf("%d, %d, %d\n", MaxNum1, MaxNum2, MaxNum3);
}
void constAndPointer() { int a = 10, b = 20;
const int *p1;
int const *p2;
int * const p3 = &a; //c++中必须要初始化
p1 = &a;
p2 = &a;
p1 = &b;
p2 = &b;
/*
错误
*p1 = 20;
*p2 = 20;
p3 = 100;
p3 = &b;
*/
/*
在最后一种情况下,指针是只读的,也就是 p3 本身的值不能被修改;
在前面两种情况下,指针所指向的数据是只读的,也就是 p1、p2 本身的值可以修改(指向不同的数据),但它们指向的数据不能被修改。
*/
//只读不能修改
const int * const p4 = &a;
int const * const p5 = &b;
/*
记忆方法
const 离变量名近就是用来 修饰 指针变量
离 变量名 远 就是用来 修饰 指针指向的数据
如果 近的和远的 都有,那么就 同时 修饰 指针变量 以及它 指向的数据
*/
}
void constAndPointerParameter() { /* 在C语言中,单独定义 const 变量没有明显的优势,完全可以使用#define命令代替。 const 通常用在函数形参中,如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用 const 来限制。
在C语言标准库中,有很多函数的形参都被 const 限制了,下面是部分函数的原型:
size_t strlen(const char * str);
int strcmp(const char * str1, const char * str2);
char * strcat(char * destination, const char * source);
char * strcpy(char * destination, const char * source);
int system(const char* command);
int puts(const char * str);
int printf(const char * format, ...);
*/
}
//使用 const 对形参加以限制,例如查找字符串中某个字符出现的次数: size_t strnchr(const char * const str, char ch) { // str[1] = ‘s’; //如果不加以const 修饰 可以改变 实参里内存空间的数据 形参也会改变 //str = “I Love C”; //加两个const双重限制 str只能读 int i, n = 0, len = strlen(str);
for (i = 0; i<len; i++) {
if (str[i] == ch) {
n++;
}
}
return n;
}
//const 和非 const 类型转换 / 也就是说,const char 和char 是不同的类型,不能将const char 类型的数据赋值给char 类型的变量。 但反过来是可以的,编译器允许将char 类型的数据赋值给const char *类型的变量。
这种限制很容易理解,char 指向的数据有读取和写入权限, 而const char 指向的数据只有读取权限,降低数据的权限不会带来任何问题,但提升数据的权限就有可能发生危险。 */
void func(char *str) { } int main8122() { constBae();
char str[] = "http://c.biancheng.net";
char ch = 't';
int n = strnchr(str, ch);
printf("%d\n", n);
printf("%s\n", str);
const char *str1 = "c.biancheng.net";
//char *str2 = str1; // const 赋值给非 const
//func(str1); // const 赋值给非 const
char *str2 = "Hello";
str1 = str2; //非 const 赋值给 const可以
printf("%s\n", str2);
system("pause");
return 0;
}
结论
- 指针变量和它所指向的内存空间变量,是两个不同的概念。。。。。。
- 看const 是放在*的左边还是右边看const是修饰指针变量,还是修饰所指向的内存空变量