C语言 内存和地址

内存与地址

在介绍指针之前,先让我来讲一讲计算机内存与地址。计算机内存可以看作是一辆火车,我们知道火车有很多节车厢,每一节车厢都有车厢编号(坐过火车的人都知道),每一节车厢就可比喻为计算机的一块内存,车厢里面有座位号,通过座位号就可以唯一的确定一个座位,座位号就好在这一个内存块的偏移量,通过它可以唯一确定的数据存储的位置。

注意,内存中的每个位置由一个独一无二的地址标识,内存中的每个位置都包含一个值。

现在举例说明内存中数据存储,如下表,表中加粗边框部分表示内存中实际存储的数据,无边框部分表示内存单元的地址。


10000


10004


10006


10008


10012


10016


110


-1


16


1234567890


10000


10008

仔细的人也许会看到,对-1或16只占了两个字节,可粗略看作为short int类型数据, 110在内存中占了4个字节,可粗略看作是int类型,而1234567890则可粗略看作是浮点型数据,所以应该了解虽然是同样一块地址,也可能存放不同类型的数据。

如果你能记住一个值的存储地址,你就可能根据这个地址取得这个值。但是要记住所有这些地址实在是太笨拙了(因为内存的地址并不像上表中表示的那么简单),所以高级语言所提供的特性之一就是通过名字而不是地址来访问内存的位置。下面这张表与上表相同,但这次使用名字来代替地址。


a


b


c


d


e


f


110


-1


16


1234567


10000


10008

从上表中可以看出,当地址抽象成我们比较容易接受的名字时,对编程来说就变得简单,这些名字就是传说中的变量。不过有一点非常重要,你必须记住,名字与内存位置之间关联并不是硬件所提供的,它是由编译器为我们实现的。所有的这些变量给了我们一种更方便的方法记住地址——硬件仍然通过地址访问内存位置

好了,我们再来看看上面的两张表,我有一个问题,对于变量e中存储的内容到底代表一个值还是一个地址呢?

问题很简单,不能确定。

例1:

int a = 110;

int *e = &a;

例1中e代表一个地址,这个地址指向了整型变量a。

例2

int e = 10000;

例2中e则代表一个值。

我们已经知道定义变量时需要类型,编译器实现了变量与内存位置之间关联,那变量的类型又是干什么呢?变量名相当于帮我们找到了那个内存,而变量类型则告诉编译器从变量所指向的那个内存位置起取几个字节。如int a =110; 则是从10000(a对应内存地址)起取4个字节,所以从10000到10003这段地址就是变量a存储的空间,从而变量a共有232个取值。

而short int b = -1;代表从10004开始取sizeof(short int)个字节,也就是10004、10005这2个字节。其他的可以以此类推。

针对类型我们可以这样理解,还是拿坐火车为例,当一个出行的时候,买一张票就可以,这种情况相当于(char类型);某一天刚好和女朋友出去旅游,买一张票显然不够了,就得买2张票(short int类型);如果一个宿舍4个人准备去旅游显示就得4张票(int,float类型);以此类推。火车相对不同的人不同需求分配座位,内存同样根据不同的变量分配不同的内存空间。理解了这些,对于复杂的类型如数组、结构体、联合体变量的定义内存分配就明白了。

时间: 2024-09-30 20:55:06

C语言 内存和地址的相关文章

c语言内存四区模型

c语言内存四区模型:代码区,全局区(常量区),栈区,堆区 在全局区(常量区),两个字符串完全一样c++编译器只会定义一份 char * getBuf() { char buf[20]; strcpy(buf, "abcde"); return buf; } abcdX?  有乱码! 确实把内存地址返回了,但不能用 被调函数调用完毕,在临时区分配的内存统统消失 char *buf= (char *)malloc(sizeof(char)*20); 手动malloc申请一份内存,由程序员手

C语言内存使用的常见问题及解决之道

一  前言 本文所讨论的“内存”主要指(静态)数据区.堆区和栈区空间(详细的布局和描述参考<Linux虚拟地址空间布局>一文).数据区内存在程序编译时分配,该内存的生存期为程序的整个运行期间,如全局变量和static关键字所声明的静态变量.函数执行时在栈上开辟局部自动变量的储存空间,执行结束时自动释放栈区内存.堆区内存亦称动态内存,由程序在运行时调用malloc/calloc/realloc等库函数申请,并由使用者显式地调用free库函数释放.堆内存比栈内存分配容量更大,生存期由使用者决定,故

c语言内存模型

文章一.C语言的内存分配模型 1.程序代码区:存放函数体的二进制代码. 2.全局区数据区:全局数据区划分为三个区域.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域.常量数据存放在另一个区域里.这些数据在程序结束后由系统释放.我们所说的BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称. 3.栈区:由编译器自动

C语言内存分布

C语言内存分布 典型的C语言程序内存表示分区共有5个部分: 正文段 Text segment 已初始化数据段(数据段)Initialized data segment 未初始化数据段(bss)Uninitialized data segment 堆 Stack 栈 Heap 具体分布图 各个分区的作用 正文段 CPU执行的机器指令部分 通常可共享 常常是只读的 已初始化数据段(数据段) 包含程序中需明确赋初始值的变量 保存已经初始化的全局变量 未初始化数据段(BSS) 在程序开始执行之前,内核将

C语言 内存四区与函数调用模型

C语言提高笔记 标签(空格分隔): C++ C语言 day1 数组做函数参数的退回问题 数组做函数参数会退回为一个指针, 正确做法:把数组的内存首地址和数组的有效长度传给被调用函数. 实参的a 和 形参的a 的数据类型本质不一样, 形参中的数组,编译器会把它当成指针处理 只会分配四个字节. 形参写在函数上,和写在函数内是一样的,只不过是具有对外的属性而已. 数据类型本质分析 数据类型可理解为创建变量的模具(模子):是固定内存大小的别名: 数据类型的作用:编译器预算对象(变量)分配的内存空间大小

Eclipse 官方简体中文语言包下载地址及安装方法

Eclipse 官方简体中文语言包下载地址及安装方法 打开Eclipse Babel Project 主页: http://www.eclipse.org/babel/downloads.php 根据Eclipse的版本找到相应的插件地址,复制下来. 进入Eclipse,选择Help->Install New Software... 点击Add按钮,把刚才复制的地址粘贴到Location:,再随便取一个名字. 等待Pending一会儿,再在Babel Language Packs in Chin

常见的C语言内存错误及对策(转)

http://see.xidian.edu.cn/cpp/html/483.html 一.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内存.浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.结构体成员指针未初始化 struct student {    char *name;    int score; }stu,*pstu; intmain() {    strcpy(stu.name,"Jimy");    stu.score =

C语言内存调试技巧—C语言最大难点揭秘

本文将带您了解一些良好的和内存相关的编码实践,以将内存错误保持在控制范围内.内存错误是 C 和 C++ 编程的祸根:它们很普遍,认识其严重性已有二十多年,但始终没有彻底解决,它们可能严重影响应用程序,并且很少有开发团队对其制定明确的管理计划.但好消息是,它们并不怎么神秘.引言C 和 C++ 程序中的内存错误非常有害:它们很常见,并且可能导致严重的后果.来自计算机应急响应小组(请参见参考资料)和供应商的许多最严重的安全公告都是由简单的内存错误造成的.自从 70 年代末期以来,C 程序员就一直讨论此

【ThinkingInC++】6、内存存放地址的地方

/** * 功能:内存存放地址的地方 * 时间:2014年8月10日11:01:08 * 作者:cutter_point */ #include<iostream> using namespace std; //全局变量的存放地点 int dog, cat, bird, fish; //函数存放内存地点 void f(int pet) { cout<<"pet id number: "<<pet<<endl; } int main() {