这段代码中 char * const pq=p; 应当怎么理解,或者赋值后*q的值是怎样的 *q=*(q+1); q++; 又该怎么理解;

已解决问题
已知质数p,q满足3p+5q=31,求p/3q+1的值?请帮忙
浏览次数:628
用手机阿里扫一扫
最满意答案
可以知道p、q都是10以内的质数进而可以很快得出p=2,q=5所以p/3q+1=2/(3*5+1)=1/8
答案创立者
以企业身份回答&
正在进行的活动
生意经不允许发广告,违者直接删除
复制问题或回答,一经发现,拉黑7天
快速解决你的电商难题
店铺优化排查提升2倍流量
擅长&nbsp 店铺优化
您可能有同感的问题
扫一扫用手机阿里看生意经
问题排行榜
当前问题的答案已经被保护,只有知县(三级)以上的用户可以编辑!写下您的建议,管理员会及时与您联络!
server is ok当前位置: >
有以下程序
#include &stdio.h&
voidfun1(char*p)
while(*q!='\0')
chae a[]={&Program&},*p;
printf(&%s\n&,a);
程序执行后的输出结果是()。
A.Prohsbn&
B.Prphsbn&
C.Progsbn&
D.Program
所属学科:
试题类型:客观题
所属知识点:
试题分数:1.0 分
暂无学习笔记。
&&&&&&&&&&&&&&&希赛网 版权所有 & &&C语言使用中指针和内存泄漏的问题和解决方案
对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏。这些的确是消耗了开发人员大多数调试时间的事项。指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是一旦您了解了指针及其关联内存操作的基础,它们就是您在 C 语言中拥有的最强大工具。
本文将与您分享开发人员在开始使用指针来编程前应该知道的秘密。本文内容包括:
●导致内存破坏的指针操作类型
●在使用动态内存分配时必须考虑的检查点
●导致内存泄漏的场景
如果您预先知道什么地方可能出错,那么您就能够小心避免陷阱,并消除大多数与指针和内存相关的问题。
什么地方可能出错?
有几种问题场景可能会出现,从而可能在完成生成后导致问题。在处理指针时,您可以使用本文中的信息来避免许多问题。
未初始化的内存
在本例中,p已被分配了 10 个字节。这 10 个字节可能包含垃圾数据,如图 1所示。
char *p = malloc ( 10 );
图1.垃圾数据
如果在对这个p赋值前,某个代码段尝试访问它,则可能会获得垃圾值,您的程序可能具有不可预测的行为。p可能具有您的程序从未曾预料到的值。
良好的实践是始终结合使用memset和malloc,或者使用calloc。
char *p = malloc (10);
memset(p,&&,10);
现在,即使同一个代码段尝试在对p赋值前访问它,该代码段也能正确处理Null值(在理想情况下应具有的值),然后将具有正确的行为。
由于p已被分配了 10 个字节,如果某个代码片段尝试向p写入一个 11 字节的值,则该操作将在不告诉您的情况下自动从其他某个位置&吃掉&一个字节。让我们假设指针q表示该内存。
图2.原始 q 内容
图3.覆盖后的 q 内容
结果,指针q将具有从未预料到的内容。即使您的模块编码得足够好,也可能由于某个共存模块执行某些内存操作而具有不正确的行为。下面的示例代码片段也可以说明这种场景。
char *name = (char *) malloc(11);
// Assign some value to name
mpy ( p,name,11); // Problem begins here
在本例中,memcpy操作尝试将 11 个字节写到p,而后者仅被分配了 10 个字节。
作为良好的实践,每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。一般情况下,memcpy函数将是用于此目的的检查点。
内存读取越界
内存读取越界 (overread) 是指所读取的字节数多于它们应有的字节数。这个问题并不太严重,在此就不再详述了。下面的代码提供了一个示例。
char *ptr = (char *)malloc(10);
char name[20] ;
memcpy ( name,ptr,20); // Problem begins here
在本例中,memcpy操作尝试从ptr读取 20 个字节,但是后者仅被分配了 10 个字节。这还会导致不希望的输出。
内存泄漏可能真正令人讨厌。下面的列表描述了一些导致内存泄漏的场景。
●重新赋值我将使用一个示例来说明重新赋值问题。
char *memoryArea = malloc(10);
char *newArea = malloc(10);
这向如下面的图 4所示的内存位置赋值。
图4.内存位置
memoryArea和newArea分别被分配了 10 个字节,它们各自的内容如图 4所示。如果某人执行如下所示的语句(指针重新赋值)&&
memoryArea = newA
则它肯定会在该模块开发的后续阶段给您带来麻烦。
在上面的代码语句中,开发人员将memoryArea指针赋值给newArea指针。结果,memoryArea以前所指向的内存位置变成了孤立的,如下面的图 5所示。它无法释放,因为没有指向该位置的引用。这会导致 10 个字节的内存泄漏。
图5.内存泄漏
●在对指针赋值前,请确保内存位置不会变为孤立的。
●首先释放父块假设有一个指针memoryArea,它指向一个 10 字节的内存位置。该内存位置的第三个字节又指向某个动态分配的 10 字节的内存位置,如图 6所示。
图6.动态分配的内存
free(memoryArea)
如果通过调用 free 来释放了memoryArea,则newArea指针也会因此而变得无效。newArea以前所指向的内存位置无法释放,因为已经没有指向该位置的指针。换句话说,newArea所指向的内存位置变为了孤立的,从而导致了内存泄漏。
每当释放结构化的元素,而该元素又包含指向动态分配的内存位置的指针时,应首先遍历子内存位置(在此例中为newArea),并从那里开始释放,然后再遍历回父节点。
这里的正确实现应该为:
free( memoryArea-&newArea);
free(memoryArea);
返回值的不正确处理
有时,某些函数会返回对动态分配的内存的引用。跟踪该内存位置并正确地处理它就成为了calling函数的职责。
char *func ( )
return malloc(20); // make sure to memset this locaon to &&&
void callingFunc ( )
func ( ); // Problem lies here
在上面的示例中,callingFunc()函数中对func()函数的调用未处理该内存位置的返回地址。结果,func()函数所分配的 20 个字节的块就丢失了,并导致了内存泄漏。
归还您所获得的
在开发组件时,可能存在大量的动态内存分配。您可能会忘了跟踪所有指针(指向这些内存位置),并且某些内存段没有释放,还保持分配给该程序。
始终要跟踪所有内存分配,并在任何适当的时候释放它们。事实上,可以开发某种机制来跟踪这些分配,比如在链表节点本身中保留一个计数器(但您还必须考虑该机制的额外开销)。
访问空指针
访问空指针是非常危险的,因为它可能使您的程序崩溃。始终要确保您不是在访问空指针。
本文讨论了几种在使用动态内存分配时可以避免的陷阱。要避免内存相关的问题,良好的实践是:
●始终结合使用memset和 malloc,或始终使用calloc。
●每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。
●在对指针赋值前,要确保没有内存位置会变为孤立的。
●每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应首先遍历子内存位置并从那里开始释放,然后再遍历回父节点。
●始终正确处理返回动态分配的内存引用的函数返回值。
●每个malloc都要有一个对应的 free。
●确保您不是在访问空指针。
原文标题:C语言中的指针和内存泄漏
文章出处:【微信号:jingzhenglizixun,微信公众号:机器人博览】欢迎添加关注!文章转载请注明出处。
发布评论请先
一、五大内存分区 内存分成5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在....
在日常的开发中,有很多地方会用到Foundation和UIKit,使用之前需要先将头文件%23imp....
内存分成5个区,它们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
1.建一个目录
2.写代码,建一个hello.c文件
命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译 器给我们输出的可执....
当程序运行到需要一个动态分配的变量时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量....
上一节中已经抽象出了位置性 PID 和增量型 PID 的数学表达式,这一节,重 点讲解 C 语言代码....
学什么单片机最有前途? 这是单片机初学者经常问的问题。对于这个问题,我想没有人敢下定论。因为每一种单....
|| 或操作,|| 为界将表达式分为两部分,他会先算前一部分,如果前一部分为真,他将停止运算,如果为....
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处....
1:malloc是由程序员在堆栈动态开辟空间 2:返回值开辟空间的首地址,但是类型是void *,需....
使用C语言编写流水灯程序。
单片机应用的核心技术是什么?是按键,数码管,流水灯,串口。是它们的程序框架。按键和数码管是输入是....
硬件描述语言一般是用来描述电气的编程方式。这些语言对于一些机器人专家来说是相当熟悉的,因为他们习惯 ....
简述ARM Linux内核启动三个阶段的功能。
在嵌入式系统中对GUI的基本要求是什么?
const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
1.static关键字
这个关键字前面也有提到,它的作用是强大的。
要对static关键字深入了....
辛辛苦苦学习C语言究竟有什么用?
模块划分的"划"是规划的意思,意指怎样合理的将一个很大的软件划分为一系列功能独立的部分合作完成系统的....
单片机定时器的使用可以说非常简单,只要掌握原理,有一点的C语言基础就行了。要点有以下几个:
这个关键字前面也有提到,它的作用是强大的。要对static关键字深入了解,首先需要掌握标准C程序的组....
计算机发展初期,程序员就是使用这些二进制形式的CPU指令来编写程序的。
乘除法很消耗CPU资源,查看汇编代码会发现,一个乘除法运算会编译出10几甚至几10行代码。如果是乘以....
比如int类型在大多数16位CPU构架中占用两个字节,但在32位CPU中却往往占用4个字节;char....
市面上介绍C语言以及编程方法的书数目繁多,但对如何编写优质嵌入式C程序却鲜有介绍,特别是对应用于单片....
在C和C++语言开发中,指针、内存一直是学习的重点。因为C语言作为一种偏底层的中低级语言,提供了大量....
数字钟是一种利用数字电路来显示秒、分、时的计时装置,与传统的机械钟相比,它具有走时准确、显示直观、无....
C 语言测试是招聘嵌入式系统程序员过程中必须而且有效的方法。这些年,我既参加也组织了许多这种测试,在....
设备的可靠性涉及多个方面:稳定的硬件、优秀的软件架构、严格的测试以及市场和时间的检验等等。这里着重谈....
当你在一个项目小组做一个相对较复杂的工程时,意味着你不再独自单干。你需要和你的小组成员分工合作,一起....
相传在C的世界里出现了一件极品装备(铁布衫)const、它的出现,让天下的所有刺客和黑客都闻风丧胆,....
每个变量和其名字一样善变,有时候它善变是发自内心的,有时候是外部因素决定的,只有volatile变量....
4个重要算法C语言实现源代码
很多初学者都会问我“我想学C,该怎么开始呢?”今天我们就来聊一聊属于初学者必须懂的知识希望小伙伴们能....
等类似问题。面对这些问题,我们只能发出由衷的感慨:世界上还有很多有意义的事情等着我们去消化摄入的食物....
本文档介绍的主要内容是20例基于单片机C语言的基础程序设计详细资料概述
本设计是通过AT89S52单片机来实现俄罗斯方块游戏的设计,使用C语言进行编程,并通过Proteus....
基于51单片机的激光雕刻机c语言程序设计及相应电路图的设计详细资料概述
对C语言部分的指针写的很细,值得学习中文版免费下载
 一部介绍标准C语言及其程序设计方法的权威性经典著作。全面、系统地讲述了C语言的各个特性及程序设计的....
C语言的经典算法大全包括了51个算法的详细中文概述
C语言函数手册详细资料大全(免费下载) 包括了各种C语言函数的:功能,用法,程序例
除代码的可读性之外,程序的执行时间还主要依赖于做决定时所选择的条件结构类型。许多硬件工程师都熟悉简单....
ATPCS规则体现了一种模块化设计的思想,其基本内容是C模块(函数)和汇编模块(函数)相互调用的一套....
如何学习DSP技术
1)DSP的速度较快,DSP的硬件系统需要考虑时序。
2)DSP的指令较复杂....
顺序语句就是从上到下没有判断,一步到底的语句。选择语句就是if和switch语句,在特定的场合,sw....
现在的编程代码全部都是英文,有没有可能有一天编程代码全是中文呢?而且如果当年计算机由中国人发明,编程....
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司
电信与信息服务业务经营许可证:粤B2-C语言指针详解----指针声明定义赋值
C语言的指针是让新手很头疼的事情,但是由于其太过于灵活,以至于可以很好得的解决一些复杂的问题,因此不得不掌握。我最近正在学习指针相关的内容,因此在这里做一个小的总结。本篇是不涉及到函数以及结构体等复杂的使用方法,仅仅讨论一下指针的基本使用方法。
首先我们区分 * 和 & ,这两个运算符, & 我们在scanf函数中经常使用。为了方便理解我们看下面这行代码:
int *p =a;
定义了一个指向a的整型指针,那么有p=& *p =a;
即指针变量的值是地址(&a),*可以理解为取地址 (*p 可以看成 *(&a)取出&a这个地址中的值)。
下面我们看一个复杂点的代码:
int n =0,*p = &n,**q = &p;
这里出现了二级指针,也就是所谓的&指向指针的指针&。 q是指向 int* 型数据的指针变量,首先 p = &n,这行代码很好理解,后面的**q = &p可以拆开来看,首先声明了一个int* 型数据的指针变量 int **q;再给指针型变量赋值 即(*q) = &p;那么问题来了,对于指针的赋值应该如何理解呢?就以上面这行定义为例有下面四个赋值语句
p = 1; *q = 2;q =*p = 5;
我们先看 p = 1;这个赋值语句,根据我们上面所解释的p =&a;我们知道指针变量的值应该是地址,而p = 1;直接将整数赋给了指针变量,编译时会报错
cannot convert from 'const int' to 'int *'
我们再看 *q = 2;根据上面的分析我们知道(*q) = &p;同第一句一样的问题编译时会报错cannot convert from 'const int' to 'int *'
再来看第三句 q = 这句很明显的错了,p是 int* 型数据 而 q是int**型数据,编译时会报错cannot convert from 'int ** ' to 'int *'
我们根据上述p=& *p =a;可以明显的看到 *p = 5;这是一个正确的赋值语句。}

我要回帖

更多关于 char *p,*q 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信