文档库 最新最全的文档下载
当前位置:文档库 › 指针PointerPointer指针变量占用的内存空间

指针PointerPointer指针变量占用的内存空间

C指针函数习题

C++指针函数习题 一、选择题 1.以下程序的运行结果是()。 sub(int x, int y, int *z) { *z=y-x; } void main() { int a,b; sub(10,5,&a); sub(7,a,&b); cout< #include<>

操作系统实验之内存管理实验报告

学生学号 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称 计算机操作系统 开 课 学 院 计算机科学与技术学院 指导老师姓名 学 生 姓 名 学生专业班级 2016 — 2017 学年第一学期

实验三 内存管理 一、设计目的、功能与要求 1、实验目的 掌握内存管理的相关内容,对内存的分配和回收有深入的理解。 2、实现功能 模拟实现内存管理机制 3、具体要求 任选一种计算机高级语言编程实现 选择一种内存管理方案:动态分区式、请求页式、段式、段页式等 能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等 能够选择分配、回收操作 内购显示进程在内存的储存地址、大小等 显示每次完成内存分配或回收后内存空间的使用情况 二、问题描述 所谓分区,是把内存分为一些大小相等或不等的分区,除操作系统占用一个分区外,其余分区用来存放进程的程序和数据。本次实验中才用动态分区法,也就是在作业的处理过程中划分内存的区域,根据需要确定大小。 动态分区的分配算法:首先从可用表/自由链中找到一个足以容纳该作业的可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分成为已分配区,剩下部分仍为空白区。最后修改可用表或自由链,并回送一个所分配区的序号或该分区的起始地址。 最先适应法:按分区的起始地址的递增次序,从头查找,找到符合要求的第一个分区。

最佳适应法:按照分区大小的递增次序,查找,找到符合要求的第一个分区。 最坏适应法:按分区大小的递减次序,从头查找,找到符合要求的第一个分区。 三、数据结构及功能设计 1、数据结构 定义空闲分区结构体,用来保存内存中空闲分区的情况。其中size属性表示空闲分区的大小,start_addr表示空闲分区首地址,next指针指向下一个空闲分区。 //空闲分区 typedef struct Free_Block { int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block; 定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情况。其中pid作为该被分配分区的编号,用于在释放该内存空间时便于查找。size表示分区的大小,start_addr表示分区的起始地址,process_name存放进程名称,next指针指向下一个分区。 //已分配分区的结构体 typedef struct Allocate_Block { int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct Allocate_Block *next; } Allocate_Block; 2、模块说明 2.1 初始化模块 对内存空间进行初始化,初始情况内存空间为空,但是要设置内存的最大容量,该内存空间的首地址,以便之后新建进程的过程中使用。当空闲分区初始化

变量的指针和指针变量的区别是什么

2变量的指针和指针变量的区别是什么。 答;一个变量的地址指出了变量的存储单元在内存中的具体位置,能对变量进行存取操作。这个变量的地址就是变量的指针。指针是一种具有特殊意义的整型数,指针不能存放在一般的整型变量中,必须存放在专门指针的变量中,这类变量就是指针变量。 3 一维数组元素的引用有哪些方式。 答;下标法、地址法、指针法 4 2维数组列地址有哪些计算方法。 答;1 根据数组元素所在的行计算出行地址,然后把行地址转换成行中首元素的地址,再根据数组元素所在的列计算数组元素的地址。 2 根据2维数组的数组元素在存储空间上按行连续存放的特点,每个数组元素的地址等于2维数组元素的首元素地址加上该数组元素相对于首元素位置的偏移量。 3把2维数组的每一行当作一个一维数组,用一维数组元素地址的计算方法计算相应的2维数组元素的地址。 第9章结构体与共用体 1 什么是链表。其中单向链表具有哪些特点。 答;链表是若干个同样类型的结构通过依次串接方式构成的一种动态数据结构。链表中的每一个结构体数据成为结点,链表可以分成单向链表和双向链表 单向链表的特点;1 链表中的结点数据可以改变的 2 结点占用的内存是动态分配内存和动态释放内存函数。 2 对单向链表的常用操作有哪些。 答;对单向链表的常用操作有建立、显示、插入,删除和查找。 3 什么是共用体。 答;共用体是一个集合体。它的各个成员的数据类型可以是不相同的,所有成员共享同一段存储空间,存储空间的大小取决存储单元最大的成员的数据类型。 4 指向结构体类型变量的指针变量引用形式有哪些。 答;有两种形式;【星号指针变量名】。成员名和指针变量名-大于号成员名。 第10章位运算及编译预处理 1 C提供的编译预处理功能有哪些。如何实现。 答;功能有三种;宏定义、文件包含和条件编译,分别用宏定义命令、文件包含命令、条件编译命令实现。 2 文件包含的基本功能是什么。 答;文件包含处理是一个源文件可以将另一个源文件的全部内容包含到本文件中来,作为本文件的一部分,这可以节省程序设计人员的重复劳动。 【3【在C语言中提供了几种什么样的位运算符。 答;-、小于小于、大于大于、 4 文件包含需要注意哪些问题 答;一个井include命令只能指定一个被包含文件,包含多个文件侧需多个井include命令;文件包含可以嵌套,即一个被包含文件中可以包含另一个被包含的文件;在井include命令中,文件名可以用双引号或尖括号括起来。 第11章文件 1 文件的结束标志有哪些。 答;每个文件都有一个结束标志。当文件的位置指针移到文件的结束标志处时,表示文件结束。如何测试文件是否结束,常有2种方法 1 ASCII码文件的结束标志用【-1】表示。

指向函数的指针

指向函数的指针 c/c++ 2010-11-20 13:17:02 阅读41 评论0 字号:大中小订阅首先看这个程序: #include using namespace std; void max(int a, int b) { cout<<"now call max("<b?a:b; cout<

我曾经写过一个命令行程序,有很多命令,于是构着了一个结构的数组,大概是这样 struct{ char *cmd_name; bool (*cmd_fun)(); }cmd_info_list[MAX_CMD_NUM]; 程序中得到一个用户输入的命令字符串后,就匹配这个数组,找到对应的处理函数。 以后每次添加一个命令,只需要加个函数,然后在这个数组中加一个记录就可以了,不需要修改太多的代码。 这可以算是一种用法吧。呵呵。 Windows 中,窗口的回调函数就用到了函数指针。 用VC向导 New Projects ----> Win32 Application ----> A typical "Hello World!" application 其中的WndProc 是WNDPROC 类型的函数typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM); WndProc 作为窗口的回调函数,用来填充WNDCLASSEX 结构。 WNDCLASSEX wcex; wcex.lpfnWndProc = (WNDPROC)WndProc; void ListTraverse(LinkList L,void (*visit)(int)) { Link p; p=L->next; while(p) { visit(p->data); p=p->next; } return OK; } void print(int c) { printf("%d",c); } ListTraverse(L,print); 这算是个例子吧??? #include #include #include double Add (double x, double y) { return x+y; } double Sub (double x, double y) { return x-y; } double Mul (double x, double y)

关于堆栈和指针(指针例子解释很好)

关于堆栈和指针 堆栈是一种执行“后进先出”算法的数据结构。 设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。 堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减1。这个过程叫做“弹出pop”。如此就实现了后进先出的原则。 堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。 堆栈可以用数组存储,也可以用以后会介绍的链表存储。 下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。 #define MAX_SIZE 100 typedef int DATA_TYPE; struct stack { DATA_TYPE data[MAX_SIZE]; int top; }; 堆栈是系统使用是临时存储区域。它是后进先出的数据结构。 C++主要将堆栈用于函数调用。当函数调用时,各种数据被推入堆栈顶部;函数终止后的返回地址、传递给函数的参数、函数返回的结果以及函数中声明的局部变量等等。因此当函数A调用函数B调用函数C,堆栈是增长了,但调用完成后,堆栈又缩小了。 堆是一种长期的存储区域。程序用C++的new操作符分配堆。对new的调用分配所需的内存并返回指向内存的指针。与堆栈不同,你必须通过调用new明确的分配堆内存。你也必须通过调用C++的delete 操作符明确的释放内存,堆不会自动释放内存。 如果C++中的一个类是定义在堆栈上的,就使用"."开访问它的成员。如果是定义在堆上的,就使用"->"指针来开访问。但在,"->"操作符也可以用在堆栈上的类。 什么是指针? 和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实

动态内存管理知识总结

1.标准链接库提供四个函数实现动态内存管理: (1)分配新的内存区域: void * malloc(size_t size); void *calloc(size_t count , size_t size); (2)调整以前分配的内存区域: void *realloc(void *ptr , size_t size); (3)释放以前分配的内存区域: void free(void *ptr); 2.void * malloc(size_t size); 该函数分配连续的内存空间,空间大小不小于size 个字节。但分配的空间中的内容是未知的。该函数空间分配失败则返回NULL。 3.void *calloc(size_t count , size_t size); 该函数也可以分配连续的内存空间,分配不少于count*size个字节的内存空间。即可以为一个数组分配空间,该数组有count个元素,每个元素占size个字节。而且该函数会将分配来的内存空间中的内容全部初始化为0 。该函数空间分配失败则返回NULL。 4. 以上两个分配内存空间的函数都返回void * (空类型指针或无类型指针)返回的指针值是“分配的内存区域中”第一个字节的地址。当存取分配的内存位置时,你所使用的指针类型决定如何翻译该位置的数据。以上两种分配内存空间的方法相比较,calloc()函数的效果更好。原因是它将分配得来的内存空间按位全部置0 。 5. 若使用上述两种分配内存的函数分配一个空间大小为0 的内存,函数会返回一个空指针或返回一个没有定义的不寻常指针。因此绝不可以使用“指向0 字节区域”的指针。 6. void *realloc(void *ptr , size_t size); 该函数释放ptr所指向的内存区域,并分配一个大小为size字节的内存区域,并返回该区域的地址。新的内存区域可以和旧的内存区域一样,开始于相同的地址。且此函数也会保留原始内存内容。如果新的内存区域没有从原始区域的地址开始,那么此函数会将原始的内容复制到新的内存区域。如果新的内存区域比较大,那么多出来部分的值是没有意义的。 7. 可以把空指针传给realloc()函数,这样的话此函数类似于malloc()函数,并得到一块内存空间。如果内存空间不足以满足内存区域分配的请求,那么realloc()函数返回一个空指针,这种情况下,不会释放原始的内存区域,也不会改变它的内容。 8. void free(void *ptr); 该函数释放动态分配的内存区域,开始地址是ptr,ptr的值可以是空指针。若在调用此函数时传入空指针,则此函数不起任何作用。 9. 传入free() 和realloc()函数的指针(若不为空指针时)必须是“尚未被释放的动态分配内存区域的起始地址”。否则函数的行为未定义。Realloc()函数也可以释放内存空间,例如:Char *Ptr = (char *)malloc(20); 如只需要10个字节的内存空间,且保留前十个字节的内容,则可以使用realloc()函数。 Ptr = Realloc(ptr,10); // 后十个字节的内存空间便被释放

Windows内存管理机制

Windows内存管理机制 在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用;根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制。 本文目的: 对Windows内存管理机制了解清楚,有效的利用C++内存函数管理和使用内存。 本文内容: 本文一共有六节,由于篇幅较多,故按节发表。其他章节请看本人博客的Windows内存管理及C++内存分配实例(一)(二)(三)(四)和(五)。 1. 进程地址空间 2.内存状态查询函数 3.内存管理机制--虚拟内存 (VM) 4.内存管理机制--内存映射文件 (Map) 5.内存管理机制--堆 (Heap) 使用场合 操作系统为每个线程都建立一个默认堆栈,大小为1M。这个堆栈是供函数调用时使用,线程内函数里的各种静态变量都是从这个默认堆栈里分配的。

堆栈结构 默认1M的线程堆栈空间的结构举例如下,其中,基地址为0x0004 0000,刚开始时,CPU的堆栈指针寄存器保存的是栈顶的第一个页面地址 0x0013 F000。第二页面为保护页面。这两页是已经分配物理存储器的可用页面。 随着函数的调用,系统将需要更多的页面,假设需要另外5页,则给这5页提交内存,删除原来页面的保护页面属性,最后一页赋予保护页面属性。 当分配倒数第二页0x0004 1000时,系统不再将保护属性赋予它,相反,它会产生堆栈溢出异常STATUS_STACK_OVERFLOW,如果程序没有处理它,则线程将退出。最后一页始终处于保留状态,也就是说可用堆栈数是没有1M的,之所以不用,是防止线程破坏栈底下面的内存(通过违规访问异常达到目的)。

第8章 善于利用指针(1)

内存管理指针的基本概念指针应用实例指针作函数参数第8章指针(1)

复习回顾 上次课的内容: ◆局部变量和全局变量 ◆变量的作用域 ◆变量的生存期 ◆声明与定义 ◆内部函数 ◆外部函数◆你开始习惯写函数了吗? 2012是如何实现的?假定造成世界末日的上帝是一个程序员,作为一名合格的程序员,他绝不应该写出类似于“摧毁地球”这样的程序,而应该写一个“摧毁(行星)”的函数,然后把地球作为参数传进去!

C语言新手的晋级之路 第一步:萧规曹随 ◆在这一步要求按照教材或讲义上的程序实例进行原样 输入,运行一下程序看是否正确。 ◆在这一步,掌握C语言编程软件的使用方法(包括新 建、打开、熟练输入、编辑、保存、关闭C程序); 初步记忆新学章节的知识点;养成良好的编程风格( 是讲义提倡的而不是教材上的) ◆难点:小心数字1和字母l,字母o和数字0,中英文标 点符号的区别

C语言新手的晋级之路 第二步:移花接木 ◆在第一步输入的C程序的基础上进行试验性的修改, 运行一下程序看一看结果发生了什么变化,分析结果变化的原因,加深新学知识点的理解。 ◆可与第一步同步进行,“输入”可加深记忆,“修改 ”可加深理解,二者相辅相成,互相促进。 ◆友提,一次进行一处修改即可,免得把自己改晕了。

C语言新手的晋级之路 第三步:无中生有 ◆面对教材的例子题目,不参考教材,自己从头开始编 写程序。看能否写出正确运行的代码。 ◆初学者易犯的错误:scanf格式控制和输入不匹配或把变量 名当地址作参数,使用未定义的变量、漏掉或多写“;”、“{” 与“}”、“(”与“)”不匹配,控制语句(选择、分支、循环)的格式不正确,调用库函数没有包含相应头文件,调用未声明 的函数、调用函数时实参和形参不匹配、数组边界越界等等 ◆要学会看编程工具的错误信息提示:双击错误提示光标可 跳转到发生错误的行,如果该行没有错误就往前查找。错误要一 个一个修改,每改完一次编译一下程序。

指针与内存详解.

在计算机领域,堆栈是一个不容忽视的概念,但是很多人甚至是计算机专业的人也没有明确堆栈其实是两种数据结构。 堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top对数据项进行插入和删除。 要点: 堆:顺序随意 栈:后进先出(Last-In/First-Out [编辑本段]堆和栈的区别 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后由系统释放。 4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。 5、程序代码区—存放函数体的二进制代码。 二、例子程序 这是一个前辈写的,非常详细 //main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main( {

int b; 栈 char s[] = "abc"; 栈 char *p2; 栈 char *p3 = "123456"; 123456\0在常量区,p3在栈上。 static int c =0;全局(静态)初始化区 p1 = (char *malloc(10; p2 = (char *malloc(20; } 分配得来得10和20字节的区域就在堆区。 strcpy(p1, "123456"; 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 [编辑本段]堆和栈的理论知识 1.申请方式 stack: 由系统自动分配。例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 heap: 需要程序员自己申请,并指明大小,在c中malloc函数 如p1 = (char *malloc(10; 在C++中用new运算符 如p2 = new char[20];//(char *malloc(10; 但是注意p1、p2本身是在栈中的。 2.申请后系统的响应

DELPHI和C指针与内存分配比较

delphi和c指针与内存分配比较 1.动态变量 对于动态分内存的变量,使用System单元的下面两个函数: procedure New(var P:Pointer);//为变更分配内存 procedure Dispose(var P:Pointer);//释放内存 其中P为变量地址 示例: type Str18=string[18]; var P:^Str18; begin New(P); P^:='Now you see it...'; Dispose(P);{Now you don't...} end; ///////////////////////////// Delphi里自己管理内存的两对函数new(),dispose()和getmem(),freemem() delphi的指针 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。因此,说指针是C语言的灵魂,一点都不为过。同时,这种说法也让很多人产生误解,似乎只有C语言的指针才能算指针。Basic不支持指针,在此不论。其实,Pascal语言本身也是支持指针的。从最初的Pascal发展至今的Object Pascal,可以说在指针运用上,丝毫不会逊色于C 语言的指针。 以下内容分为八部分,分别是 一、类型指针的定义 二、无类型指针的定义 三、指针的解除引用 四、取地址(指针赋值) 五、指针运算 六、动态内存分配 七、字符数组的运算 八、函数指针 一、类型指针的定义。对于指向特定类型的指针,在C中是这样定义的: int*ptr; char*ptr; 与之等价的Object Pascal是如何定义的呢? var ptr:^Integer; ptr:^char; 其实也就是符号的差别而已。 二、无类型指针的定义。C中有void*类型,也就是可以指向任何类型数据的指针。Object Pascal为其定义了一个专门的类型:Pointer。于是, ptr:Pointer; 就与C中的 void*ptr; 等价了。 三、指针的解除引用。要解除指针引用(即取出指针所指区域的值),C的语法是(*ptr),ObjectPascal则是ptr^。 四、取地址(指针赋值)。取某对象的地址并将其赋值给指针变量,C的语法是 ptr=&Object; Object Pascal则是 ptr:=@Object; 也只是符号的差别而已。

C语言——指向函数的指针

1函数类型(* 函数指针变量)();//指向函数的入口地址 一个函数是若干语句的集合,经编译后存储在函数代码存储区,并占有一片连续的存储空间,对函数指针只能用函数名赋值而无其他运算 1#include 2 3int max(int x ,int y); 4 5int main() 6{ 7int(* p)() ;//定义p是指向函数的指针变量 8int a , b , c ; 9 10p= max ;//将函数max的入口地址赋给指针变量p 11scanf("%d %d",&a ,&b) ; 12c= (* p)(a , b) ;//用指向函数的指针变量p调用函数 13printf("a = %d , b = %d , max = %d", a , b , c); 14 15return0; 16} 17 18int max(int x ,int y) 19{ 20int k ; 21k= (x> y)? x : y ; 22 23return k ; 24} 函数名作为实际参数: 1 #include 2 3int fun1(int a , int b) 4 { 5return a+b ; 6 } 7 8int fun2(int (*q)() , int x , int y) 9 { 10return (*q)(x , y) ; 11 } 12 13int main() 14 { 15int (*p)() , k ; 16 p = fun1 ;

17 k = fun2( p , 8 , 5 ) ; 18 19printf("k = %d \n" , k); //输出 13 20 21return0 ; 22 } 设置一个函数proc ,每次调用它会实现不同的功能,输入 a , b 两个数,第一次调用proc时,找出两者中最大者,第二次找出最小者,第三次调用求两数之差: 1 #include 2 3int max(int *x , int *y); 4int min(int *x , int *y); 5int a_b(int *x , int *y); 6int proc(int *x , int *y , int(*p)()); 7 8int main() 9 { 10int a , b ; 11 12printf("Enter a and b :"); 13scanf("%d %d" , &a , &b); 14 15printf("a = %d \t b = %d \n" , a , b); 16 17printf("max(%d,%d) = " , a , b); 18 proc(&a , &b , max); 19 20printf("min(%d,%d) = " , a , b); 21 proc(&a , &b , min); 22 23printf("%d - %d = " , a , b); 24 proc(&a , &b , a_b); 25 26return0 ; 27 } 28 29int max(int *x , int *y) 30 { 31int k ; 32 33 k = (*x > *y) ? *x : *y ; 34 35return k ; 36 } 37 38int min(int *x , int *y)

CC++指针常见内存错误NULL指针野指针分析

C/C++指针和内存的相关问题分析 一、C/C++指针和内存的相关问题 以前在用C/C++编程的时候,经常会遇到内存读写错误,内存泄露等问题,后来记得看过一篇文章,大体意思阐述了“内存观念”全面贯彻到整个C/C++工程开发过程中的重要性和意义。因为C/C++较底层,指针的应用灵活而又功能强大,所以开发过程中,对内存的理解和把握非常必要。我今天看了几篇文章是针对C++指针和内存的一些分析和总结,觉得写的很好。我在此归纳总结了其中的一部分,包括常见的内存错误分析和NULL指针、野指针的介绍。 1.常见的内存错误及其对策 发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。常见的内存错误及其对策如下: (1)内存分配未成功,却使用了它;编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。 (2)内存分配虽然成功,但是尚未初始化就引用它;犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略。 (3)内存分配成功并且已经初始化,但操作越过了内存的边界;例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。 (4)忘记了释放内存,造成内存泄露;含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。动态内存的申请与释放必须配对,程序中malloc 与free的使用次数一定要相同,否则肯定有错误(new/delete同理)。 (5)释放了内存却继续使用它;有三种情况:A程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。B函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结

C语言程序设计 指针变量的定义

6.1.3指针变量的定义 前面提到的存放地址的变量是一种特殊的变量,它只能用来存放地址而不能用来存放其他类型(例如整型、实型、字符型等)的数据,需专门定义。“指针”表示指向关系,所谓指针就是地址。一个变量的指针就是这个变量的地址,存放地址的变量称为指针变量。例如:pa 是一个指针变量,pa 中存放的是整型变量a 的地址,也就是说pa 指向变量a。变量a 的地址就是变量a 的指针,一个指针变量的内容一定是另一个变量在内存中的地址。 定义形式为: 数据类型说明符 *标识符; 例如: int *p; 表示定义了一个指针变量p,它指向一个整型变量,即p 存放一个整型变量的地址。 说明: (1)“数据类型说明符”是指该指针变量所指向变量的类型;(2)“标识符”就是所定义的指针变量的名字; (3)定义一个指针变量必须用符号“*”,它表明其后的变量是指针变量,但不要认为“*p”是指针变量,指针变量是p 而不是*p; (4)指针可以指向任何类型的对象。 在定义了一个指针变量p 以后,系统为这个指针变量分配一个存储单元(一般为2个字节),用来存放地址。要使一个指针变量指向某个变量,必须将该变量的地址赋给该指针变量。 例如: int a,b;int *p1,*p2; p1=&a;p2=&b; 上述语句表示定义了两个整型变量a,b 和两个指针变量p1,p2,然后将a 的地址赋给p1,b 的地址赋给p2,这样p1指向变量a, p2指向变量b。 6.1.4指针变量的引用 定义了一个指针变量后,可以对该指针变量进行各种操作,操作时用到两个有关指针的运算符: (1)&:取地址运算符。(2)*:指向运算符。 例如:&a 为变量a 的地址,*p 为指针变量p 所指向的变量。【例6-1】定义指向整型变量的指针 /*程序名:6_1.c*/#include &a &b p1 a p2b 图6-3指针的指向

指向对象的指针变量

指向对象的指针变量 定义的一般形式: 类名*指针变量名; p-> (*p). 指向对象的成员变量的指针变量: 1.该指针变量可出现在成员函数中,通过获取该成员变量的地址,然后通过(*指针变量名)访问该成员变量 class aa { int a; public: aa() { a=0; } aa(int a) { this->a=a; } void get_a() { int *p; p=&a; cout<<*p<a=a; } void get_a() { int *p; p=&a; cout<<*p<

} }; int main() { aa b(3); b.get_a(); aa *p; p=new aa[2]; (p+1)->get_a(); p[1].get_a(); int *q; q=&b.a; return 0; } 指向成员函数的指针变量: 定义的一般形式: 函数类型名(类名::*指针变量名)(参数); 赋值的一般形式: 指针变量名=对象名.成员函数名 指针变量名=&类名.成员函数名或指针变量名=类名.成员函数名通过指针变量引用对象的成员函数 一般形式:(对象名.*指针变量名)(参数) this指针 #include using namespace std; class aa { int a; public: aa() { a=0; } aa(int a) { this->a=a; } void get_a() { cout<a<

c语言中动态内存申请与释放的简单理解

c语言中动态内存申请与释放的简单理解 在C里,内存管理是通过专门的函数来实现的。与c++不同,在c++中是通过new、delete函数动态申请、释放内存的。 1、分配内存 malloc 函数 需要包含头文件: #include 或 #include 函数声明(函数原型): void *malloc(int size); 说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。 从函数声明上可以看出。malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如: int *p; p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int); 或: int* parr; parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为sizeof(int) * 100; 而 malloc 则必须由我们计算需要的字节数,并且在返回后强行转换为实际类型的指针。 int* p; p = (int *) malloc (sizeof(int)); 第一、malloc 函数返回的是 void * 类型,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。 第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成:

C++指针与动态分配内存new关键字专题

本文作者:黄邦勇帅 本文是学习C++的基础内容,指针是C或C++所特有的,因此应熟练掌握指针的使用,本文集中介绍C或C++中的各种指针,包括指针数组,数组指针,常量(const)指针,指向指针的指针,尤其是对二维数组和指针进行了详细精辟的解释,在读完本文的二维数组和指针的讲解之后,相信你就会对指针有一个车底的了解了。 本文内容完全属于个人见解与参考文现的作者无关,其中难免有误解之处,望指出更正。 声明:禁止抄袭本文,若需要转载本文请注明转载的网址,或者注明转载自“黄邦勇帅”。 主要参考文献: 1、C++.Primer.Plus.第五版.中文版[美]Stephen Prata著孙建春韦强译人民邮电出版社2005年5月 2、C++.Primer.Plus.第四版.中文版Stanley B.Lippman、Barbara E.Moo著李师贤等译人民邮电出版社2006年3月 3、C++.Primer.Plus.第三版.中文版Stanley B.Lippman等著潘爱民张丽译中国电力出版社2002年5月 4、C++入门经典第三版[美]Ivor Horton著李予敏译清华大学出版社2006年1月 5、C++参考大全第四版[美]Herbert Schidt著周志荣朱德芳于秀山等译电子工业出版社2003年9月 6、21天学通第四版C++ [美]Jesse Liberty著康博创作室译人民邮电出版社2002年3月 第一部分:指针 11.1 基础 1.指针是一个变量,它存储着另一个变量或函数的地址,也就是说可以通过指针间接地引用变量。指针变量包含一个地址,而且可以存储任何数据类型的内存地址,但指针变量却被声明为特定的数据类型,一个指向整型数据类型的指针不能存储一个浮点型的变量地址。 2.指针声明的形式为,数据类型*指针变量名;其中*星号是指针运算符,例如int *x;声明x为int型指针.11.2 指针运算符*和&地址运算符 1.&地址运算符是一元运算符,能反回它的操作数的内存地址.如y=&x;把变量x的地址输入到y中,它与x的值无关,比如x的值为1000,而x的地址为55则,y将接收到地址55. 2.*指针运算符是一元运算符,它是&运算符的相反形式,*运算符能反回位于其操作数所指定的地址的变量的值.例如y = &x;z = *y;假设x的值为1000,地址为55,则第二条语句说明z的值为1000,*y把由y所指向的内存的地址的变量x的值赋给z。*运算符可理解为“在地址中”,则z=*y可描术为“z接收了在址址y中的值。”,3.其实可以把*y当成一个变量来使用,即可以为*y赋值等,例如*y=100;(*y)++;等,但要注意的是对*y的操作相当于是对此指针指向的地址中的变量的操作,即对*y=100的赋值语句,相当于是x=100,而(*y)++则相当于x++。11.3 指针的运算 0.指针只支持4种算术运算符:++,――,+,-.指针只能与整数加减.指针运算的原则是:每当指针的值增加时,它将指向其基本类型的下一个元素的存储单元.减少时则指向上一个元素的存储单元. 1.++,――运算符,假设int型x的地址为200,且int型占4个字节,定义int *p;p=&x;则p++的地址将是204,而不是201,因为当指针p的值增加时,它都将指向下一个int型数据.减少时也是这样,如p――则,p的地址将是196.2.+,-,运算符,注意两个指针不能相加.例int *p;p=&x;假设x的地址为200,则p+9将的指针地址将是200+4*9=236,即p指向了从当前正指向的元素向下的第9个元素. 3.两指针相减,同类型的一个指针减去另一个指针的值将是两个指针分开的基本类型的元素的个数. 11.4 指针和数组 1.在C++语言中使用没有下标的数组名会产生一个指向数组中第一个元素的指针.如char x[20];char *p;p=x;此语句说明将x数组的第一个元素的地址赋给指针p. 2.*(p+4)和x[4]两句都可以访问数组中第5个元素,这里假设int x[33];int *p;p=x;因为p是指向数组x的第一个元素地址的指针,而p+4就是指向第五个元素的指针,而*(p+4)就是第五的个元素了. 3.p[i]语句相当于*(p+i)或x[i]即数组中第i+1个元素的值,假设char x[20];char *p;p=x; 11.5 字符串常量

C++指针与动态分配内存new关键字专题

第一部分:指针 11.1 基础 1.指针是一个变量,它存储着另一个变量或函数的地址,也就是说可以通过指针间接地引用变量。指针变量包含一个地址,而且可以存储任何数据类型的内存地址,但指针变量却被声明为特定的数据类型,一个指向整型数据类型的指针不能存储一个浮点型的变量地址。 2.指针声明的形式为,数据类型*指针变量名;其中*星号是指针运算符,例如int *x;声明x为int型指针.11.2 指针运算符*和&地址运算符 1.&地址运算符是一元运算符,能反回它的操作数的内存地址.如y=&x;把变量x的地址输入到y中,它与x的值无关,比如x的值为1000,而x的地址为55则,y将接收到地址55. 2.*指针运算符是一元运算符,它是&运算符的相反形式,*运算符能反回位于其操作数所指定的地址的变量的值.例如y = &x;z = *y;假设x的值为1000,地址为55,则第二条语句说明z的值为1000,*y把由y所指向的内存的地址的变量x的值赋给z。*运算符可理解为“在地址中”,则z=*y可描术为“z接收了在址址y中的值。”,3.其实可以把*y当成一个变量来使用,即可以为*y赋值等,例如*y=100;(*y)++;等,但要注意的是对*y的操作相当于是对此指针指向的地址中的变量的操作,即对*y=100的赋值语句,相当于是x=100,而(*y)++则相当于x++。11.3 指针的运算 0.指针只支持4种算术运算符:++,――,+,-.指针只能与整数加减.指针运算的原则是:每当指针的值增加时,它将指向其基本类型的下一个元素的存储单元.减少时则指向上一个元素的存储单元. 1.++,――运算符,假设int型x的地址为200,且int型占4个字节,定义int *p;p=&x;则p++的地址将是204,而不是201,因为当指针p的值增加时,它都将指向下一个int型数据.减少时也是这样,如p――则,p的地址将是196.2.+,-,运算符,注意两个指针不能相加.例int *p;p=&x;假设x的地址为200,则p+9将的指针地址将是200+4*9=236,即p指向了从当前正指向的元素向下的第9个元素. 3.两指针相减,同类型的一个指针减去另一个指针的值将是两个指针分开的基本类型的元素的个数. 11.4 指针和数组 1.在C++语言中使用没有下标的数组名会产生一个指向数组中第一个元素的指针.如char x[20];char *p;p=x;此语句说明将x数组的第一个元素的地址赋给指针p. 2.*(p+4)和x[4]两句都可以访问数组中第5个元素,这里假设int x[33];int *p;p=x;因为p是指向数组x的第一个元素地址的指针,而p+4就是指向第五个元素的指针,而*(p+4)就是第五的个元素了. 3.p[i]语句相当于*(p+i)或x[i]即数组中第i+1个元素的值,假设char x[20];char *p;p=x; 11.5 字符串常量

相关文档
相关文档 最新文档