const是在ANSI C中追加的修饰符,它将类型修饰为“只读”。
const 不一定代表常量。其主要用于修饰函数的参数。无论如何用const修饰变量名,只意味着其“只读”。
char *my_strcpy (char *dest,
const
char *src);
{
src = NULL;
}
如果想把src自身定义为只读,需要如下修改
char *my_strcpy(char
*dest, char *
const src);
{
src = NULL;
}
如果将src和src指向的对象都定义为只读,可写成这样:
char *my_strcpy(char
*dest, const char *
const src);
{
src = NULL;
*src = ‘a’;
}
现实中,当指针作为参数时,const常常用于将指针指向的对象设定为只读。
通常, C的参数都是传值。因此,无论被调用方对参数进行怎样的修改,都不会对调用方做成任何影响;
如果想要影响调用方的变量(通过函数参数将函数内的一些值返回),可以将指针作为参数传递给函数;
解读const声明的规则
1. 从标识符开始,使用英语由内向外顺序地解释下去;
2. 一旦解释完毕的部分的左侧出现了const,就在当前位置追加read-only;
3.
如果解释完毕的部分左侧出现了数据类型的修饰符,并且其左侧存在const,姑且先去掉数据类修饰符,追加read-only;
4. 在翻译成中文的过程中,const修饰的是紧跟在它后面的单词;
例:
char * const src
解读
src is a read-only pointer to char;
char const * src
解读
src is a pointer to read-only char;
注意
char const * src
和
const char * src
的意思完全相同
一旦给指针类型的参数设定了const,当前层次下的函数就必须全部使用const*
typedef struct {
char *title;
int
price;
char isbn[32];
…
…
…
} BookData;
将上边的结构体作为输入参数的函数原型,可以写成这样:
void regist_book (BookData
const * book_data);
因为使用了const,所以book_data所指向的对象是禁止改写的。现在可以将BookData传递给这个函数了…
但是,在被传递的数据中,book_data—>title,即“标题”所指向的内容是可以被改写的。这是因为根据指定的const而成为“只读”的对象只是“book_data所指向的对象自身”,而不包括“book_data所指向的对象再向前追溯到的对象”;
需要把结构体修改一下:
typedef struct{
char const
*title;
int
price;
char
isbn[32];
…
…
} BookData;
这样就无法修改title所指向的对象了
Q:const 可以代替 #define 吗?
通常,C使用预处理器的宏功能定义常量:
#define HOGE_SIZE ( 100 )
…
int hog [ HOGE_SIZE ];
但是,预处理器是独立于C语法的。so 在调试时 常出现问题
由宏定义自身的问题造成的错误往往爆发在使用它的地方, 这给纠错带来麻烦
将宏改写为:
const
int HOGE_SIZE = 100;
int
hoge[ HOGE_SIZE ] ;
也是不行的!
因为尽管C 中 数组的元素个数必须为常量,HOWEVER,
const修饰的标识符不是常量,仅仅是“read-only”而已,因此上边的语法是错误的。