一、指针——保存地址的变量
指针式C语言中一种特殊的变量,其作用是保存其他变量的地址。
可以把指针想象成一个指向某个特定位置的箭头,这个箭头指向的就是其他变量在内存中的存储地址。
定义指针变量的一般形式为:
数据类型 *指针变量名;
- 数据类型:指针所指向的变量的类型
如果指针要指向一个整型变量,那么数据类型就是int;如果指向一个字符型变量,数据类型就是char。
[1] 示例
#include <stdio.h>
int main() {
int num = 30;
// 定义一个指向int类型的指针变量
int *ptr;
// 让ptr指向num的地址
ptr = #
return 0;
}
- 指针不仅可以 int *ptr也可以写成 int* ptr ,都表示一个指向整型变量的指针 ptr 。
- ptr = # 让指针 ptr 指向了变量 num 的地址。
- 此时,ptr 中保存的就是 num 在内存中的地址。
1.指针变量
指针变量的类型必须和它所指向的变量类型一致,这是因为不同类型的变量在内存中占用的存储空间大小不同,访问方式也不同。
如,整型变量通常占用4个字节,字符型变量通常占用1个字节。
[1]示例
#include <stdio.h>
int main() {
double d = 3.14;
// 定义一个指向double类型的指针变量
double *dptr = &d;
return 0;
}
- double d = 3.14; 定义了一个双精度浮点型变量d。
- double *dptr = &d; 定义了一个指向双精度浮点型变量的指针 dptr,并让它指向了变量d的地址。
- 由于dptr的类型是 double,与d的类型double一致,所以这个赋值是合法的。
如果指针类型和所指向的变量类型不一致,可能会导致未定义行为,例如访问错误的内存区域或得到错误的结果。
二、&取地址运算
1.运算符&的作用
在C语言中,&是取值运算符,它的核心功能是获取变量在计算机内存中的存储地址,
计算机的内存就像是一个巨大的箱子,每个变量都被存放在这个房间都被存放在这个箱子的某个特定位置,而&运算符能够找出变量所在的具体位置。
从硬件层面来看,内存由一系列连续的存储单元组成的,每个存储单元都有唯一的编号,这个编号就是地址。
当我们定义一个变量时,编译器会为该变量分配一定数量的存储单元,&运算符返回的就是这些存储单元的起始地址。
#include <stdio.h>
int main() {
int num = 10;
// 获取num变量的地址
int *address = #
printf("变量num的地址是: %p\n", address);
return 0;
}
⬇️
上述输出的结果是一个以十六进制表示的地址值,0x是十六进制数的前缀。
- int num = 10; 定义了一个整型变量num并初始化为10。
- 编译器会在内存中为num分配4个字节(在大多32位和64位系统上)的存储空间。
- &num 操作获取了这4个字节存储空间的起始地址,然后将这个地址赋值给了指针变量address。
2.printf结合%p取地址
printf函数是C语言中用于格式化输出的函数,%p 是它用于输出指针地址的格式说明符。
当使用%p 时,printf 会以十六进制的形式输出指针所指向的内存地址。
在不同的操作系统和编译器环境下,指针的长度可能不同。
如,在32位系统中,指针通常是32位(4个字节);在64位系统中,指针通常是64位(8个字节)。
%p 会自动适应指针的长度,确保正确输出地址。
#include <stdio.h>
int main() {
int num = 20;
printf("变量num的地址是: %p\n", &num);
return 0;
}
⬇️
- &num 获取了变量 num 的地址。
- %p 会将这个地址以十六进制的形式输出。
每次运行程序时,变量num可能会被分配到不同的内存地址,所以给出的地址值可能会不同。
3.&不能取的地址
(1)常量
常量是在程序运行过程中值不能被改变的量,它在内存中没有固定的存储位置。
常量可以是字面常量(如10、3.14)等,也可以是使用const关键字定义的常量。
由于常量没有明确的存储地址,所以不能对其使用取地址运算符。
// 错误示例
// int *p = &10;
10是一个字面常量,它没有在内存中分配一个特定的存储位置,因此不能使用&来获取它的地址。
(2)表达式结果
像 a+b 这样的表达式结果也不能取地址。
表达式的计算结果通常是一个临时值,它在内存中没有固定的存储位置,只是在计算过程中临时存在于寄存器或栈中。
#include <stdio.h>
int main() {
int a = 1, b = 2;
// 错误示例
// int *p = &(a + b);
return 0;
}
上述 a+b 的结果是一个临时值,它没有在内存中分配一个固定的位置,所以不能使用&来获取它的地址。
(3)访问地址上的变量
通过解引用(允许程序直接操作内存)运算符*,可以访问指针所指向地址上的变量。
#include <stdio.h>
int main() {
int num = 60;
int *ptr = #
// 通过解引用操作访问num的值
printf("num的值是: %d\n", *ptr);
return 0;
}
int *ptr = # 让指针ptr指向了变量num 的地址。
*ptr 通过解引用操作访问了ptr 所指向的变量,也就是num,因此printf函数输出的是num的值。
小结
介绍了指针的基础知识以及地址运算符。