#includeintmian(){int a =0;int* pa =&a;*pa =100;return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1
2
3
4
5
6
7
8
9
上述代码中*pa = 100;就运用了解引用操作符,* pa 的意思是:通过pa存放的地址,找到其指向的空间,那么*pa其实就是变量 a 了;使用*pa = 100;就是把
a
a
a 变成了 100.
2.4、指针变量的大小
前面的学习中,我们了解到,32位的机器设有32根地址总线,每根线只有两种状态:即有电流通过和无电流通过,逻辑上表示 0 和 1 ,这与二进制序列的表示相符。我们把32位的地址总线产生的二进制序列看成一个地址,那么这个地址一共有32个
b
i
t
bit
bit 位,即 4 个字节才能存储。
同理,64位的机器,存储地址需要 8 个字节的空间。
32位平台下地址是32个
b
i
t
bit
bit 位,指针变量大小是 4 个字节
64位平台下地址是64个
b
i
t
bit
bit 位,指针变量大小是 8 个字节
注意:指针变量的大小与类型无关,只要他是指针变量,他的大小就是 4 字节或 8 字节。
三、指针变量类型的意义
3.1、 指针的解引用
我们得知,指针变量的大小和类型无关,那么为什么还要有各种各样的指针类型呢?
C语言当然不可能无缘无故创造这么多类型,他们都是有意义的,让我们一起往下看。
下面,我们来看看两段代码:
#includeintmain(){int n =0x11223344;int* pi =&n;*pi =0;return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1
2
3
4
5
6
7
8
9
#includeintmain(){int n =0x11223344;char* pc =(char*)&n;*pc =0;return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1
2
3
4
5
6
7
8
9
从调试我们可以看到,代码 1 会将
n
n
n 的 4 个字节全部改为 0 ,而代码 2 只是将
n
n
n 的第一个字节改为 0。
指针的类型决定了对指针解引用时,指针有多大的访问权限(一次能操作几个字节)
例如:
c
h
a
r
char
char* 只能访问 1 个字节,
i
n
t
int
int* 能访问 4 个字节
3.2、 指针 ± 整数
让我们先来看一段代码,观察他们的地址变化
#includeintmain(){int n =10;char* pc =(char*)&n;int* pi =&n;printf("&n =%p\n",&n);printf("pc =%p\n", pc);printf("pc+1 =%p\n", pc +1);printf("pi =%p\n", pi);printf("pi+1 =%p\n", pi +1);return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
运行结果:
我们可以看到,
c
h
a
r
char
char* 类型 +1 跳过了 1 个字节,
i
n
t
int
int* 类型 +1 跳过了 4 个字节。
这是因为
c
h
a
r
char
char * 指针类型所指向的
c
h
a
r
char
char 类型大小是 1 个字节 ,同理,
i
n
t
int
int * 所指向的
i
n
t
int
int 类型大小是 4 个字节
指针的类型决定了指针向前或向后走一步有多大
3.3、
v
o
i
d
void
void * 指针
在所有指针类型中,还有一种特殊的指针:
v
o
i
d
void
void * 指针。我们知道
v
o
i
d
void
void 用在函数的返回类型和参数中时,表示无返回值、无参数,那么
v
o
i
d
void
void * 指针又表示什么呢?
#includeintmain(){int a =10;int* pi =&a;char* pc =&a;return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1
2
3
4
5
6
7
8
9
我们可以看到,将一个
i
n
t
int
int 类型的变量地址赋值给一个
c
h
a
r
char
char * 类型的指针变量。编译器给出了警告,因为类型不兼容,要想消除这个警告,除了强制类型转换成
c
h
a
r
char
char * 类型,还可以用
v
o
i
d
void
void *类型接收。
如下:
#includeintmain(){int a =10;void* pi =&a;void* pc =&a;*pi =10;*pc =0;return0;}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
1
2
3
4
5
6
7
8
9
10
11
12
VS编译器运行结果: 我们可以看到,虽然用
v
o
i
d
void
void * 类型接收编译器并没有报警告,但是却无法解引用,编译器直接报错,那么
v
o
i
d
void
void * 类型有什么用呢?
一般
v
o
i
d
void
void * 类型用在函数参数部分,用来接收未知类型数据的地址的,这样设计可以达到泛型编程的效果。使得一个函数可以处理多种类型的数据。
评论记录:
回复评论: