typedef struct dictNode { int key; char *value; struct dictNode *next; } Dict;
和get()函数是这样的:
char *get(const Dict *dict,int key) { if(!dict) return NULL; Dict *currPtr = dict; while(currPtr) { if(currPtr->key == key) { return currPtr->value; } currPtr = currPtr->next; } }
编译此代码会产生以下错误:
dict.c:85:警告:初始化从指针目标类型中丢弃限定符
此警告涉及以下行:
Dict *currPtr = dict;
如果我在该行之前添加“const”,如下所示:
const Dict *currPtr = dict;
警告消失了……
1)我不明白的第一件事就是:我在get()中的dict参数中添加了“const”,这样编译器会在我尝试更改dict指向的地址时警告我,否则我将无法访问主程序中的字典导致我丢失了我指向的地址.现在,我正在创建一个新指针currPtr,它指向与dict相同的位置.这样,我使用这个指针来遍历字典并保持dict指针不变.为什么我还需要const为currPtr?
2)我不明白的第二件事是:线currPtr = currPtr-> next;正在改变currPtr指针,所以,如果我向currPtr添加一个const,为什么编译器不会警告我?
然后我有一个del()函数,如下所示:
Dict *del(const Dict *dict,int key) { if(!dict) return NULL; Dict *currPtr = dict; Dict *prevPtr = dict; while(currPtr) { if(currPtr->key == key) { prevPtr->next = currPtr->next; free(currPtr); } prevPtr = currPtr; currPtr = currPtr->next; } return dict; }
请注意,我知道这个删除功能代码不完整,如果我想删除第一个元素,它就无法正常工作.没关系,我稍后会说完,这足以证明我的问题……
3)所以,在get()函数中我需要将const添加到currPtr但是在这个del()函数中,我不需要将const添加到currPtr或prevPtr?在这两个函数中,我正在更改currPtr指针,在del()函数的情况下,我也在更改prevPtr指针.为什么get()函数要求我在currPtr之前添加一个const,而del()函数不要求我在currPtr和prevPtr之前添加一个const?
我基本上可以恢复这个帖子:我的get()和del()函数的确切时间和地点应该使用const和为什么,以及何时何地我不应该?
解决方法
const Dict currPtr
这是一个不变的Dict.现在,如果你把它作为你的指针
const Dict *currPtr
这是一个指向常量Dict的指针.这并不意味着指针是常量.但这确实意味着Dict指出被视为不变
currPtr->key = 10; // error,dict is treated as constant.
但指针不是
currPtr = otherPtr; // possible: the pointer is not constant
如果使指针保持不变,则第二种情况会出错.保持指向的dict也不变,这看起来像这样
const Dict * const currPtr = init;
现在你不能将currPtr设置为指向不同的东西,因为指针现在是常量,而不仅仅是指针所指向的那样.有些人喜欢看看const是否总是正确的东西,它使const.这看起来像这样
Dict const * const currPtr = init;
这与前一个片段相同.如果你从右到左阅读它,它会告诉你它是什么“const指向const Dict的指针”.如果您有类型,则无论您如何订购说明符
int const a = 10; const int b = 10;
两者都是常数整数.这就是为什么我们可以把const放在Dict类型说明符的右边.
现在,如果你有一个指针,你总是可以假装你指向一个常量对象,即使该对象没有被声明为const.但是,如果您指向的是const对象,则不能假装使用非const对象:
int const *p = NULL; // doesn't work without a cast. Will at least provoke a warning int *pn = p; int *p = NULL; // always works: pretending to point to something const doesn't harm. int const *pc = p;
请注意,如果将指针本身设为const,则规则与此不同.它们类似于应用于其他类型的const:
int const i = 0; int j = i; // works. we only read the value of i. its const doesn't matter. int * const p = NULL; int * q = p; // works: we only read the value of p (a null pointer).
将值复制到新变量(无论是否为指针)后,新变量不会以任何方式连接到另一个变量,因为读取的值与首先创建值的方式没有关联.另一个变量的const无关紧要.