基本术语:
声明符:“int a”就是一个声明符。
标识符: 定义的变量名字,如: int a,那么a就是一个标识符。
1.两个原则:
始终从内往外读声明符,括号优先级高。即先定位用来声明的标识符,并且从此处的开始解释。
例1.声明 char *p。首先确定标识符为p;再解析*,它代表p是指针指向;再解析char,它表示指针指向char类型。即p是指向char类型的指针。
例2.声明 void (*pf)(int)。首先确定标识符为pf,在括号内解析*,pf是指针指向;其次(int),指针指向的类型是有int参数的函数;最后void,函数返回值是void。总结:pf是一个指针,它指向了一个参数是int,返回值是void的函数
在选择符号解析顺序时,始终是先[]和()后是*。如果"*“在标识符左边且”[]"在标识符右边(例如:*p[]),那么标识符表示的是数组,而不是指针。括号同理,它表示的是函数(例如:*p())。
例:void*pf(int)。首先先解析右边的(int),pf是函数,参数是int类型;其次void*,类型为void类型的指针。总结:pf是函数,函数有一个int类型的参数,返回值是void*
复杂点的例子:
int *(*x[10])(void)。首先解析括号内[10],x是数组;其次*,数组元素是指针指向;再解析(void),指针指向不带参数的函数;最后int *,函数返回值是int类型的指针。总结:x是有10个元素的数组,它的每个元素都是一个指针,指针指向参数为空并且返回值是int*的函数
2.typedef
我们定义一个无符号整型变量x,使用:unsigned long int x;。如果要简化unsigned long int 名称,可以使用typedef, 例如:把unsigned long int改名为x,则定义:
typedef unsigned long int x;
此时x不是一个变量,而是一个简化的unsigned long int别名,但也不能再用x做变量名。
简化别名后,下面两个语句作用相同:
x b;
unsigned long int b;
上面提到的int *(*x[10])(void)复杂的声明也同样适用,它要简化为别名x,则定义:
typedef int *(*x[10])(void);
x是个自定义类型。它的类型是有10个元素的数组,数组每个元素都是一个指针,指针指向参数为空并且返回值是int*的函数。下面两个语句作用相同。
x b;
int *(*b[10])(void);
3.const
const修饰变量。使变量的地址在只读段。const char a = ‘a’; 和char const a = 'a’是一样的效果。a初始化时被赋值,a的地址在只读段,a不能再被修改。
const修饰指针变量。既可以修饰指针指向的数据,也可修饰指针本身。直接说个技巧:当const在*右边并挨着标识符时,则修饰的是指针本身;当const在*左边时,修饰指针指向的数据。以程序举例证明:
#include <stdio.h>
const char *str = "abc";
const char * const const_p = str;
const char *p = str;
int main(void)
{
printf("const pointer address:%p, const_p:%p\n", &const_p, const_p);
printf("pointer p address:%p, p:%p\n", &p, p);
return 0;
}
输出内容如下:
const pointer address:0x400600, const_p:0x4005f8
pointer p address:0x601038, p:0x4005f8
查看ELF格式文件:
$ readelf -a a.out #
...
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
...
[16] .rodata PROGBITS 00000000004005f0 000005f0
000000000000005a 0000000000000000 A 0 0 8
...
[25] .data PROGBITS 0000000000601028 00001028
0000000000000018 0000000000000000 WA 0 0 8
可以从地址分段中看出来:
const_p指向的内容在只读段。const_p的地址也被分配在只读段,所以const_p也不能再被赋值。
p指向的内容在只读段。p的地址被分配在数据段,所以p可以被修改。
注意:如果用win10的WSL运行的话,使用gdb查看运行结果。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)