存储器和指针

前言

如果真的想玩转C语言, 就需要理解C语言如何操纵存储器。

C语言在如何使用存储器方面赋予了你更多的掌控权。在本章中,你将揭开存储器神秘的面纱,看到读写变量时到底发生了什么;学习数组的工作原理,以及怎样避免烦人的存储器错误;最重要的是,你将看到掌握指针和存储器寻址对成为一名地道的C程序员来讲有多么重要。

介绍指针

什么是指针

指针就是存储器中某条数据的地址。

为什么使用指针

  1. 在函数调用时,可以只传递一个指针,而不用传递整份数据
  2. 让两段代码处理同一条数据,而不是处理两份独立的副本

指针做了两件事:避免副本和数据共享。但既然指针只是地址而已,为什么它会令很多人感到困惑呢?因为指针是一种间接形式的地址。在茫茫存储器中追逐指针,一不小心就会迷路。若是想要深究指针那就必须足够了解存储器。

介绍存储器

为了理解什么是指针,需要了解计算机的存储器。每当声明一个变量,计算机都会在存储器中某个地方为它创建空间。如果在函数(例如main()函数)中声明变量,计算机会把它保存在一个叫栈( Stack)的存储器区段中;如果你在函数以外的地方声明变量,计算机则会把它保存在存储器的全局量段(Globals)。(结合Java的JVM来进行理解)

全局变量和局部变量

  1. 局部变量:在函数中声明的变量通常保存在栈中。
  2. 全局变量:在函数外声明的变量保存在全局量区。
//以下地址,均是举例
//变量y位于全局量段,存储器地址1000000,值为1
int y=1
int main(){
	//变量x位于栈中,存储器地址为4100000,值为4
	int x=4;
	return 0;
}

假如说:计算机可能将栈中4 100 000号存储器单元分配给变量x。如果把4赋给变量x,计算机就会把4保存在4 100 000号单元。

如果想要找出变量的存储器地址,可以用&运算符:

printf("x保存在%p\n",&x);
//%p用于格式化地址。

输出结果:

总结:变量的地址告诉你去哪里找存储器中的变量,这就是为什么地址有时也叫指针,因为它指向了存储器中的变量。

按值传递参数

联想java基本变量的传值机制去思考

按指针传递参数

#include <stdio.h>

void tryChange(int* x, int* y);

int main() {
    int x = 1;
    int y = 2;
    tryChange(&x, &y);
    printf("%i\t%i", x, y);
}

// 按指针传递
void tryChange(int* x, int* y) {
    *x -= 1;
    *y -= 1;
}

输出:

0   1

此时代码不仅可以让函数返回某个值,还能让它更新某个存储器单元,只要把单元的地址传给它。

要点

  • 计算机会为变量在存储器中分配空间。
  • 局部变量位于栈中。
  • 全局变量位于全局量段。
  • 指针只是一个保存存储器地址的变量。
  • &运算符可以找到变量的地址。
  • *运算符可以读取存储器地址中的内容。
  • *运算符还可以设置存储器地址中的内容。
  • 指针是真实的地址,它是进程存储器中真实编号的地址。
  • 存储器是进程的,计算机会为每一个进程分配一个简版存储器,看起来就像是一长串字节,这里要注意将它和实际的计算机存储器进行分开分辨:
    • 实际的存储器复杂多了,但细节对进程隐藏了起来,这样操作系统就可以在存储器中移动进程,或释放并重新加载到其他位置。
    • 物理存储器的结构十分复杂,计算机通常会将存储器地址分组映射到存储芯片的不同的存储体(memorybank)。
  • 注意使用%p来打印指针,使用%li会出现警告。
  • 存储器地址是16进制表示的。
  • 读取存储器单元的内容的操作我们称之为“解引用”。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

five-five

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值