garfield

【原创】c语言程序设计之const关键字解析

0
阅读(2076)

    const,英文单词意思是:常量,常数的意思,初学者看到const这个关键字会想到常数,其实不然,const关键字定义的是变量,一个不能改变的变量,这里有点儿绕,让我慢慢给你解释,你就会明白什么是不变的变量。


下面来看关键字const的用法
1、const的普通用法
const int n = 10;
意思很明显,n是一个只读变量,程序不可以直接修改其值。这里还有一个问题需要注意,即如下使用:int a[n];在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而n只是一个变量。
2、const用于指针
const int *p;
int const *p;
int * const p;
在最后的一种情况下,指针是只读的(即p只读),而在另外两种情况下,指针所指向的对象是只读的(即*p只读)。const 是一个左结合的类型修饰符,它与其左侧的类型修饰符一起为一个类型修饰符,所以,int const 限定 *p,不限定p。int *const 限定p,不限定*p。这里有一个简便的区分方法:
沿着*号划一条线,如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。
3、const用于函数的地址传递参数
void foo(const int *p)
这种形式通常用于在数组形式的参数中模拟传值调用。也就是相当于函数调用者声称:"我给你一个指向它的指针,但你不能去修改它。"如果函数编写者遵循了这个约定,那么就相当于模拟了值传递。这也是const最有用之处了:用来限定函数的形参,这样该函数将不会修改实参指针所指的数据。这里注意了,是函数不应该去修改而不是不能修改,也就是说const不能阻止参数的修改(原因见上)。
4、const用于限定函数的返回值
const int foo();
const struct mytype foo();
上述写法限定函数的返回值不可被更新,当函数返回内部的类型时,已经是一个数值,当然不可被赋值更新,所以,此时const无意义,最好去掉,以免困惑。当函数返回自定义的类型时,这个类型仍然包含可以被赋值的变量成员,所以,此时有意义。

一、宏定义:主要是一些语法问题和技巧

例如:

#define FIND(s,e) (size_t)&(((struct s*)(0))->e)//求结构体内的变量相对于结构体的偏移量

#define SECONDS_PER_YEAR (360*24*60*60)UL//求一年中的秒数

#define MIN(a,b) (((a)<=(b))?(a):(b))//求最小值

说明:尽可能考虑移植性,由于代码可能在16位机,也有可能在32位机器上运行,所以采用size_t和UL都是基于移植性的考虑。

二、const用法:定义常量,修饰指针、函数的输入参数和返回值,简单说const表示只读的意思,本质上来说它只是在全局数据段或者栈中定义的是一个只读的常量,不是真正位于字符串常量区。Const的目的是为了产生高质量的代码,提高代码的可读性,同时保护好不能被任意改变的内存,从而降低Bug产 生的概率。

    const int a = 10;

const int b;//错误,常量必须初始化

    int a = 10,b = 9;

    const int *p1 = &a;//指针指向的内容只读,不能通过该指针去写

    *p1 = 11;//错误

    int * const p2 = &a;//指针本身只读,指针初始化到一个对象后,将不能被修改

p2 = &b;//错误

const int *p3 const = &a;//指针本身和指向的内容都是只读

const char *fp1(void) //修饰返回值,表示返回的指针指向内容只读

{

    char *p = "dddd";

    return p;

}

void fp1(const char *str)

{

    *str = 4; //错误

    const char *p = str;//p必须为const,才能接受str

}

int _tmain(int argc, _TCHAR* argv[])

{

    const char *d = fp1();

    printf("%s",d);

}