指针的基础知识及&取地址运算

一、指针——保存地址的变量

指针式C语言中一种特殊的变量,其作用是保存其他变量的地址。

可以把指针想象成一个指向某个特定位置的箭头,这个箭头指向的就是其他变量在内存中的存储地址。

定义指针变量的一般形式为:

数据类型 *指针变量名;
  • 数据类型:指针所指向的变量的类型

 如果指针要指向一个整型变量,那么数据类型就是int;如果指向一个字符型变量,数据类型就是char

[1] 示例

#include <stdio.h>

int main() {
    int num = 30;
    // 定义一个指向int类型的指针变量
    int *ptr; 
    // 让ptr指向num的地址
    ptr = &num; 
    return 0;
}
  • 指针不仅可以 int *ptr也可以写成 int* ptr ,都表示一个指向整型变量的指针 ptr
  • ptr = &num; 让指针 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 = &num; 
    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;
    // 通过解引用操作访问num的值
    printf("num的值是: %d\n", *ptr); 
    return 0;
}

int *ptr = &num; 让指针ptr指向了变量num 的地址。

*ptr 通过解引用操作访问了ptr 所指向的变量,也就是num,因此printf函数输出的是num的值。 


小结

介绍了指针的基础知识以及地址运算符。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值