C 语言一:指针、指针变量、指针变量运算
2020-08-18 本文已影响0人
望穿秋水小作坊
32 位系统中内存中每个字节的编码计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。为了正确访问这些数据,必须为每个字节都编上号码,就像门牌,身份证号一样,每个字节的编号都是唯一的,根据编号可以准确地找到某个字节。
1. 什么是指针?
- 我们将内存中的编号称为
地址(Address)
,也称为指针(Pointer)
2. 0xFFFFFFFF 地址值至少需要几个字节才能容纳?
- 1 字节(Byte) = 8 位(bit)= 256
- 16 * 16 = 256 也就是 0xF * 0xF 等价于 0xFF = 256
- 所以至少需要 4 个字节
3. 一个指针占几个字节?
- 在 64 位的操作系统上是 8 个字节,最大地址是
0xFFFFFFFFFFFFFFFF
- 在 32 位的操作系统上是 4 个字节,最大地址是
0xFFFFFFFF
#include <stdio.h>
int main(){
int a = 100;
char str[20] = "carrot";
printf("%p, %p, %lu字节 \n", &a, str, sizeof(&a));
return 0;
}
// 由于我的是 64 位系统,输出如下:
// 0x7ffeefbff548, 0x7ffeefbff550, 8字节
4. C 语言中:变量名、数组名、字符串名和函数名,哪些是指针,哪些不是指针?
- 他们本质上都是地址的助记符,但在编写代码过程中有区别。
- 我们认为
变量名
表示的是数据本身
-
数组名
、字符串名
和函数名
指的是代码块或者数据块的首地址
5. 什么是指针变量?
- 数据在内存中的地址被称为
指针
- 如果一个
变量
存储了一份数据
的指针
,我们就称它为指针变量
6. 使用指针变量
的时候,如何定义指针变量?如何给指针变量赋值?
//定义普通变量
float a = 99.5, b = 10.6;
char c = '@', d = '#';
//定义指针变量
float *p1 = &a;
char *p2 = &c;
//修改指针变量的值
p1 = &b;
p2 = &d;
-
*
是一个特殊符号,表明一个变量是指针变量,定义 p1 、p2 时必须带*
-
而给 p1、p2 赋值时,因为已经知道了它是一个指针变量,就没必要多此一举再带上
*
, 后面可以像使用普通变量一样来是使用指针变量。 -
也就是说
定义指针变量必须带*号,给指针变量赋值的时候不能带*号
-
需要强调的是,p1 、p2 的类型分别是
float*
和char*
,而不是float
和char
需要引起注意。
7. 如何通过指针变量取得数据?
- 指针变量存储了数据的地址,通过指针变量能够获得该地址上的数据,格式为
*pointer
- 这里的
*
称为指针运算符,用来取得某个地址上的数据
#include <stdio.h>
int main(){
int a = 15;
int *p = &a;
printf("%d, %d\n", a, *p); //两种方式都可以输出a的值
return 0;
}
8. 上面例子中的 *p
和 a
都能获取数据的值,它们的运行过程有什么不同?
*p 和 a 获取数据的值
-
程序被编译和链接后,a、p 被替换成相应的地址。
-
使用 *p 的话,① 通过地址
0x0000DD22
取得变量 p 本身的值,这个值是变量 a 的地址,② 再通过0x0000FF11
获取变量 a 的数据,前后共两次运算。 -
而使用 a 的话,可以直接通过
0x0000FF11
获取变量 a 的数据,只需要一步运算。
9. 假设有一个 int 类型的变量 a,pa 是指向它的指针,那么 *&a
和 &*pa
分别是什么意思呢?
-
*&a
等价于a
等价于*p
-
&*pa
等价于pa
等价于&a
10. 指针变量可以做哪些运算
- 地址的本质是一个整数
- 加法 (+1 每次跨度取决于类型 int=4 double=8 char=1)
- 减法 (-1 每次跨度取决于类型 int=4 double=8 char=1)
- 比较 (实际上就是比较地址)
- 不能对指针变量进行乘法、除法、取余等其他运算,除了会发生语法错误,也没有实际的含义