请考虑以下代码:
typedef struct Person* PersonRef;
struct Person {
int age;
};
const PersonRef person = NULL;
void changePerson(PersonRef newPerson) {
person = newPerson;
}
Run Code Online (Sandbox Code Playgroud)
出于某种原因,编译器抱怨只读值不可分配.但是const
关键字不应该使指针成为常量.有任何想法吗?
Pio*_*zmo 42
注意
typedef int* intptr;
const intptr x;
Run Code Online (Sandbox Code Playgroud)
是不一样的:
const int* x;
Run Code Online (Sandbox Code Playgroud)
intptr
是指向int的指针.const intptr
是常量指针int
,而不是指向常量的指针int
.
所以,在typedef指针之后,我不能再使它成为内容的const?
有一些丑陋的方式,比如gcc的typeof宏:
typedef int* intptr;
intptr dummy;
const typeof(*dummy) *x;
Run Code Online (Sandbox Code Playgroud)
但是,正如你所看到的,如果你知道背后的类型,那就毫无意义了intptr
.
const PersonRef person = NULL;
Run Code Online (Sandbox Code Playgroud)
是
struct Person*const person= NULL;
Run Code Online (Sandbox Code Playgroud)
所以你正在构建指针而不是对象.
小智 6
虽然问题已经通过上面的答案解决了,但我确实错过了为什么......
所以可能作为一个经验法则:
const
总是指它的前身令牌.这个规则可以真正帮助你声明指向const指针或同样整洁的东西.
无论如何,考虑到这一点,它应该明白为什么
struct Person *const person = NULL;
Run Code Online (Sandbox Code Playgroud)
声明一个指向可变结构的const指针.
想想看,你的类型定义"组"将struct Person
用指针令牌*
.所以,写作
const PersonRef person = NULL;
Run Code Online (Sandbox Code Playgroud)
你的编译器看到这样的东西(伪代码):
const [struct Person *]person = NULL;
Run Code Online (Sandbox Code Playgroud)
由于没有任何东西可以const
留下,它将令牌降级为正确的struct Person *
常数.
我想,这就是为什么我不喜欢用typedef隐藏指针的原因,而我确实喜欢这样的typedef.写作怎么样?
typedef struct Person { ... } Person;
const Person *person; /*< const person */
Person *const pointer; /*< const pointer to mutable person */
Run Code Online (Sandbox Code Playgroud)
对于编译器和人类来说,你应该很清楚,你要做什么.