c - 为什么使用 * 符号来定义指针和取消引用指针?

标签 c notation

c语言的设计者使用星号来定义指针类型是有原因的吗

int* x;

并解引用一个指针?

int y = *x;

对两个不同的事物使用相同的字符似乎令人困惑,尤其是因为它们总是在相同的上下文中使用。

最佳答案

Brian Bi 在 Quora 上对此主题有一个很好的回答.我在这里逐字重现。 http://www.quora.com/C-programming-language/Why-doesnt-C-use-better-notation-for-pointers

The fact that an asterisk is used when declaring a pointer and an asterisk is used when dereferencing a pointer is not some sort of usability glitch in C. It is intentional.

There are two other notations that work like this. You use square brackets when declaring an array, and you use square brackets when accessing an array. You use parentheses when declaring a function pointer, and you use parentheses when calling a function pointer.

Declaration follows use.

Consider the following declaration:

int *a;

This declaration tells you that *a is of type int. In other words, a is a pointer to int.

How about this:

int *a[10];

This declaration tells you that *a[i] (where i is between 0 and 9, inclusive) is of type int. Since array indexing has higher precedence than pointer dereferencing, this tells you that a is something that you can use [] on (*i.e., *an array), then use * on (i.e., a pointer)... and you will get an int as a result. In other words, a is an array[10] of pointers to int.

int (*a)[10];

This declaration tells you that (*a)[i] is of type int. Since a is something you can use * on, it must be a pointer. And then you can use [] on the result to get an int. So we see that the type of a must be pointer to array[10] of int.

Notice that the above two declarations differ only in parentheses! But you don't have to memorize where parentheses should go for every type you might want to declare. Write down how you would use the variable, and slap the final type on at the beginning, just as in the above two examples. Any parentheses you have to insert for precedence reasons, include as well in the declaration.

Many C programmers have trouble remembering how to declare function pointers. This, too, becomes easy when you remember that declaration follows use. For example, let's declare a function pointer that we could use to hold the address of the function strcpy. This variable is something that, in order to use, you first dereference (with *), then call, using (), where the parentheses contain two arguments; the first being char*, and the second const char*. And the result is a char*.

Let's call our function pointer p. The first thing we do is dereference, so we write down *p. Then we call *p with the arguments char* and const char*, so write those down in parentheses next to *p: (*p)(char*, const char*). (The parentheses are required around *p because function calling has higher precedence than dereferencing.) Finally, prepend the result of the usage, that is, the char* the function returns. So our declaration is:

char* (*p)(char*, const char*);

const is a special case. The keyword const in a declaration applies to whatever thing you would have if you only partially use the variable, but stop once you "get" to it. It means that that particular thing can't be changed.

Now, I'm sure you know that const char *s; declares a pointer to constant chars. That makes sense, since the thing at the beginning is const char, i.e., the result of *s is a const char. However, you can also write it in the form char const *s;. The interpretation is that we can "get" as far as *s, and then we see the word const, so it means what we have up to this point is const. Ignoring the const for a moment, we see char. So *s is a char, and it's also const because the word const precedes *s.

Now what about char *const s;? This means const pointer to char. The pointer can't be changed, but the thing it points to can. This is because the keyword const comes directly before s, so it "lies in the way" of the dereferencing operator, so to speak. s is const before it is dereferenced, but *s is not const. The declarations char const *const s; or const char *const s; mean const pointer to const char.

For double (and higher) pointers, it's the same deal. const char **p; declares a pointer to pointer to const char, as does char const **p;. However, char *const *p; declares a pointer to const pointer to char, and char **const p; delcares a const pointer to pointer to char.

Just remember that declaration follows use, and you'll never be confused by declaration syntax again.

关于c - 为什么使用 * 符号来定义指针和取消引用指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22740236/

相关文章:

javascript - c[num] 和 c.num 一样吗

c++ - 确定代码段的时间复杂度

c# - 这个包含尖括号的符号是什么意思?

c - fscanf 正在以某种方式更改节点(在 c 中)

c++ - 在这种情况下,int** 在 C 中意味着什么?

c - 使用 fgets() 读取文件最后一行时出现段错误

function - Dart:函数的参数表示法

C 套接字将数据附加到缓冲区被损坏

c - 不明白 tsearch 返回指针是如何工作的

algorithm - 下一个文法的复杂度是多少