精华内容
下载资源
问答
  • 今天在群里有个哥们问malloc... 不过应该有方法可以突破这个限制,在VC++2010里工程属性设置里有一个项貌似是来设置这个的,如下: 但是我设置了启用后用malloc申请大于等于2GB的内存时还是不成功,这个...

     

    今天在群里有个哥们问malloc是不是分配内存后内存指针的之前的4字节保存分配的内存大小,于是试了一下。

    Windows默认进程地址空间为2GB,也就是一个进程最多分配的内存接近2GB,但不可能达到。 不过应该有方法可以突破这个限制,在VC++2010里工程属性设置里有一个项貌似是来设置这个的,如下图:

     

    但是我设置了启用后用malloc申请大于等于2GB的内存时还是不成功,这个不知道怎么回事。

    接着说malloc的事,看其他文章(http://hi.baidu.com/cuihao0532/item/1f88ae69e4753998c5d2499b)时,里面提到分配内存后该地址的前面应该是一个结构体,这个结构体来保存分配的这段内存的相关信息,当然,内存大小是必须保存下来的,至于是不是结构体中的成员来保存这个也不清楚(我到底要说什么。。。)

    继续。。

    int *p = (int*)malloc(size);

    2GB == 1024 * 1024 * 1024 * 2 == 0x80000000,可见2GB对应为32个二进制位,也就是4字节,

    3GB == 0XC0000000, 3GB也是32位==4字节,而4GB为0x100000000,有36个二进制位,也就是需要5字节,那么也就是用来保存这个分配大小的内存尺寸对可以分配的内存大小至关重要! 这一点要知道

    在我的实验中,发现分配大于等于2GB一直都没成功,所以就暂且认为在我的环境设置下不可能申请2GB动态内存,那么只关注用来保存分配大小的4字节即可,这是前提!

     

     

    -----------说明:下面图上的红字写的“p的地址为****”, 这种说法不正确,应该是p的值是***,即p的指向为****, 下面在文字里做了更正,图上就不更正了-----

    --------------------------------------------------------------------------

    ------------------------------------------------------

    先看第一个实验,分配100字节,int类型, 100对应的二进制是0x64,

    在这个实验中, p的值为0x00406d80, 即p指向的地址为0x00406d80,堆是往高地址扩展的(栈是往低地址扩展的),为这100字节内存全都初始化为十进制的16,也就是十六进制的0x10,

    从0x00406d80往前数16字节发现了100对应的十六进制64!   需要注意的是:100可以用一个字节表示,我们无法知道作为4字节来表示的分配的100字节大小

    是从p之前的16字节开始的还是在16字节位置结束的, 虽然我们可以大概知道:高位数字字节在高地址,地位数字字节在低地址,64作为低位字节数字,那么这4字节应该是在

    64位置结束的,从而从64开始往高地址的4字节即为保存分配大小的内存单元,  我们还需要验证一下。  

    ----------------------------------------------------------------------------------------------------------------

    看下图来验证

    分配291字节内存,对应十六进制为0x123,即0x0123嘛!

    p的值为0x266d80,即p指向的内存单元的地址为0x266d80,从p指向的位置往前倒16字节,发现了23和01,通过这个说明了这个大小是

    从p倒数16字节到13字节的4字节来保存分配大小的!

     

    -----------------------------------------------------------------------------------------------------------

    下面再做一个实验

    分配了0x7FEFFFFF字节的内存

    可以发现在p指向的地址之前16到13字节处,发现了我们分配的大小,内存排列从低地址到高地址为:ff ff ef 7f, 也就是我们分配的尺寸!

     

    下面再想一个问题,我们如何用程序读出这个尺寸呢?   看下面代码

    1     cout<<"分配了"<<size3<<"字节"<<endl;
    2 
    3 
    4     int *pt = p - 16;          //p之前16字节(注意这里,陷阱!!!)
    5     UINT64 allSize = *((UINT64*)(pt)); //陷阱!
    6     cout<<"验证一下,分配了"<<allSize<<"字节"<<endl; 

     

    看上面的代码,分析一下: 由于p为int类型指针,那么我们就定义一个int  *pt来指向p之前的16字节, 这样做是不是就对了呢?

    当然不对,为什么? 因为指针减去一个数字N,减去的不是N字节,而是N * sizeof(指针类型)字节, 在这里指针为int类型,所以减去的实际是16 * sizeof(int) == 64字节,

    结果当然不对!  

    所以需要修改为  

    1 int *pt = p - 16 / sizeof(int);  //减去16字节除以int所占字节数个指针大小

     

    那么,这样结果是不是就对了呢?  发现结果还是不对,为什么呢,问题可能出现在下一句上,size3我们是用UINT64类型来定义的,那么是不是也应该用一个UINT64来接收呢?

    仔细一想,发现:size3 == 0x7FEFFFFF,size3占64位,即8字节, 我们用UINT64去接收*((UINT64*)(pt))时,转换为UINT64*再解引用是从pt开始往高地址数sizeof(UINT64)字节得到的值, 而用来保存分配尺寸的内存仅仅为4字节!!!   所以错出在了这里,我们应该从p之前16字节处开始找4字节的值来接收,所以用一个UINT可以接收的范围包括0x7FEFFFFF这个数字,我们试着把代码改成如下:

    1     cout<<"分配了"<<size3<<"字节"<<endl;
    2 
    3 
    4     int *pt = p - (16 / sizeof(int));
    5     UINT allSize = *((UINT*)(pt));
    6     cout<<"验证一下,分配了"<<allSize<<"字节"<<endl; 

     

    运行发现:这次取到的allSize和size3相等了。

     

    就说到这里,通过上述实验我发现: 细节非常非常重要!    比如指针减去一个数字N并非直接减去N字节, 而是减去N * sizeof(指针类型)字节,  还有一个数字,高位字节在高地址,低位字节在低地址等。

     

    至于malloc后,操作系统保存的其他信息今天就暂时不说了。

     

     

     

    转载于:https://www.cnblogs.com/cuish/archive/2013/04/10/3012852.html

    展开全文
  • 首先要学会看电路,比如这样的一个电路: 这里我们要端口一个高电平,灯才会亮。 再看这个电路: 这里我们需要给它一个低电平才会亮。 两个对比一下,是不是能看到特点。端口一端接地了以后,另一端接高电平。...

    如何点亮一个灯?

    点灯对初学者来说,应该是最基础的东西。简单来说,点亮一个灯光,就是控制高低电平,产生电势差,使有电流通过灯。

    如何设置高低电平?

    首先要学会看电路图,比如这样的一个电路:
    在这里插入图片描述
    这里我们要端口一个高电平,灯才会亮。
    再看这个电路:
    在这里插入图片描述
    这里我们需要给它一个低电平才会亮。
    两个对比一下,是不是能看到特点。端口一端接地了以后,另一端接高电平。端口如果接了高电平,那另一端你就给它接地。
    ok,原理清楚了,那么程序上如何实现?

    如何编写程序控制灯的电平?

    简单来说,就是
    1 找到对应的端口;
    2 端口的配置初始化
    3 给端口写入不同的电平形成通路;

    先找到需要配置的端口,这个要看电路图来找:如上图,我们要控制的,10,17,18,这三个端口`

    
    #define BOARD_LED1                        17
    #define BOARD_LED2                       18   
    #define LED                              10
    

    接着初始化,配置这些管脚为输出

    void LED_INIT(void)
    {
    	nrf_gpio_cfg_output(BOARD_LED2);
    	nrf_gpio_cfg_output(BOARD_LED1);
    	
    	nrf_gpio_cfg_output(LED);
    		
    	
    }
    

    再接着写入电平

    void led_on(void)
    {
    
    LED_INIT();
    	nrf_gpio_pin_write(BOARD_LED2, 1);
    	nrf_gpio_pin_write(BOARD_LED1, 1);
    	nrf_gpio_pin_write(LED, 0);
    
    }
    

    ok,下面直接在主函数调用led_on(),就可以直接开灯了;
    在这里插入图片描述

    如何让灯交替闪烁?

    简单来说可以通过延时函数,

    void DELAY_mS(int delaytime)    						// 延时1ms
    {
    	int i,j;
    	
    	for(i=0;i<delaytime;i++)
    		for(j=0;j<2400;j++);
    }
    
    
    void led_on(void)
    {
    
    	LED_INIT();
    	nrf_gpio_pin_write(BOARD_LED2, 1);
    	nrf_gpio_pin_write(BOARD_LED1, 1);
    	nrf_gpio_pin_write(LED, 0);
    	DELAY_mS(500;
    	nrf_gpio_pin_write(BOARD_LED2, 0);
    	nrf_gpio_pin_write(BOARD_LED1, 0);
    	nrf_gpio_pin_write(LED, 1);
    	DELAY_mS(500;
    }
    

    但是从单片机的资源使用角度,我们不推荐延时函数,而是更加优选定时器。

    定时器与延时函数

    它们两个的区别?
    延时函数在执行过程中,单片机一直在循环之中,这期间不做其他的事,一直在这里停留,直至延时结束,这样的话就比较浪费资源。
    而定时器定时的时候,单片机任然运行,定时器也在计数,定时时间到了之后,才产生中断,进而执行中断任务。
    这次点亮设备的所有灯光

    #ifndef _TEST_H_
    #define _TEST_H_
    
    #define BOARD_LED1                    17
    #define BOARD_LED2                    18
    #define LED10                         15
    #define LED9                          16   
    #define LED                            10
    #define TESTon_PERIOD           APP_TIMER_TICKS(500)              //定时时间0.5S,结束后开灯
    #define TESToff_PERIOD           APP_TIMER_TICKS(3000)              //定时时间3S,结束后关灯
    
    void Createled_ontimer(void);
    void Startled_ontimer(void);
    
    void Createled_offtimer(void);
    void Startled_offtimer(void);
    
    void All_led_on(void);
    void All_led_off(void);
    
    #endif
    
    #include "app_timer.h"
    #include "nrf_log.h"
    #include "nrf_gpio.h"
    #include "user_test.h"
    //#include "board_gpo.h"
    
    
    //创建定时器
    APP_TIMER_DEF(led_on);
    APP_TIMER_DEF(led_off);
    
    
    static void timer_led_onCallback(void *arg);
    static void timer_led_offCallback(void *arg);
    	
    void LED_INIT(void)
    {
    	nrf_gpio_cfg_output(BOARD_LED2);
    	nrf_gpio_cfg_output(BOARD_LED1);
    	nrf_gpio_cfg_output(LED9);
    	nrf_gpio_cfg_output(LED10);
    	nrf_gpio_cfg_output(LED);
    	
    }
    
    
    //LED_ON定时器
    static void timer_led_onCallback(void *arg)
    {
    	UNUSED_PARAMETER(arg);
    	
    	NRF_LOG_INFO("on");
    	LED_INIT();
    	nrf_gpio_pin_write(BOARD_LED2, 1);
    	nrf_gpio_pin_write(BOARD_LED1, 1);
    	nrf_gpio_pin_write(LED9, 1);
    	nrf_gpio_pin_write(LED10, 1);
    	nrf_gpio_pin_write(LED, 0);
    	
    Startled_offtimer();
    
    }
    void Createled_ontimer(void)
    {
    	NRF_LOG_INFO("create");
    
    	app_timer_create(&led_on,APP_TIMER_MODE_SINGLE_SHOT,timer_led_onCallback);
    
    }
    void Startled_ontimer(void)
    {
    	 NRF_LOG_INFO("start");
    	
    	app_timer_start(led_on,TESTon_PERIOD,NULL);
    
    }
    //LED_OFF定时器
    static void timer_led_offCallback(void *arg)
    {
    	UNUSED_PARAMETER(arg);
    	
    	NRF_LOG_INFO("off");
    	LED_INIT();
    	nrf_gpio_pin_write(BOARD_LED2, 0);
    	nrf_gpio_pin_write(BOARD_LED1, 0);
    	nrf_gpio_pin_write(LED9, 0);
    	nrf_gpio_pin_write(LED10, 0);
    	nrf_gpio_pin_write(LED, 1);
    	
    	Startled_ontimer();
    
    
    }
    void Createled_offtimer(void)
    {
    	NRF_LOG_INFO("create");
    
    	app_timer_create(&led_off,APP_TIMER_MODE_SINGLE_SHOT,timer_led_offCallback);
    
    }
    void Startled_offtimer(void)
    {
    	 NRF_LOG_INFO("start");
    	
    	app_timer_start(led_off,TESToff_PERIOD,NULL);
    
    }
    void All_led_on(void)
    {
    
    	nrf_gpio_pin_write(BOARD_LED2, 1);
    	nrf_gpio_pin_write(BOARD_LED1, 1);
    	nrf_gpio_pin_write(LED9, 1);
    	nrf_gpio_pin_write(LED10, 1);
    	nrf_gpio_pin_write(LED, 0);
    
    
    }
    void All_led_off(void)
    {
    
    	nrf_gpio_pin_write(BOARD_LED2, 0);
    	nrf_gpio_pin_write(BOARD_LED1, 0);
    	nrf_gpio_pin_write(LED9, 0);
    	nrf_gpio_pin_write(LED10, 0);
    	nrf_gpio_pin_write(LED, 1);
    }
    
    
    
    

    下一节讲一下nordic定时器的使用以及按键控制灯光。

    展开全文
  • 拓扑排序

    2019-11-13 23:16:58
    我们一般要学完高数和程序编程之后再学习数据结构和计算机组成原理,这就是活动和活动之间存在一些关系(优先关系) 用节点表示活动,用弧表示活动间的优先关系的有向称为AOV-网。 在AOV-网中,不应该出现有向环,...

    我们可以很轻松判断一个图有没有环,是不是有向的,但是,如何让计算机知道我们的图是否有向或者有环?

    比如说,我们软件工程的教学进度。
    我们一般要学完高数和程序编程之后再学习数据结构和计算机组成原理,这就是活动和活动之间存在一些关系(优先关系)
    用节点表示活动,用弧表示活动间的优先关系的有向图称为AOV-网。
    在AOV-网中,不应该出现有向环,因为存在环意味着某项活动应以自己为先决条件。显然这是荒谬的,若设计出这样的流程图,工程便无法进行。而对程序的数据流图中,则表明存在一个死循环。

    所谓拓扑排序就是将AOV-网中所有顶点排成一个线性序列,该序列满足:若在AOV-网中由顶点vi到顶点vj有一条路径,则在该线性序列中的顶点vi必定在vj之前

    拓扑排序算法的思想

    1.输入AOV网络,令n为顶点个数
    2.在AOV网络中选一个没有直接前驱的顶点并输出
    3.从图中删除该顶点,同时删除它所有发出的有向边
    4.重复上面2,3步骤,直到
    全部顶点均已输出,拓扑有序序列形成,拓扑排序完成或,
    图中还有没有输出的顶点,但已跳出处理循环。这说明图中还剩下一些顶点,他们都有直接前驱,再也找不到没有前驱的顶点了。这时,AOV网络必定存在有向环。

    也就是说,如果找得到拓扑结构就是一定不存在环
    找不到,一定存在环

    下面以一个小例子说明:
    在这里插入图片描述
    所以,最后得到的有向图的拓扑有序序列为:
    6,1,4,3,2,5

    展开全文
  • 学好机械制图,这2个核心要点是关键! 机械制图属于大学机械、工程类必学内容,而且...根据六个不同方向将视图分为:主视图(前视图)、后视图、左视、右视图、俯视、仰视。 但根据机械制图原理,看不见的轮廓用

    学好机械制图,这2个核心要点是关键!

    机械制图属于大学机械、工程类必学内容,而且学习周期还不短,普通大专类院校开设了一年的课程。机械制图是不是真的这么难学呢?其实非常容易。机械制图的核心关键就是看图,也就是俗称的“三视图”。只要搞懂了三视图也就基本拿下了机械制图内容。

    在这里插入图片描述

    三视图
    机械制图本身是包含六个视图,既讲零件想象在一个六方体的透明盒子中,将产品从盒子的六个方向正像投影所得到的图形。根据六个不同方向将视图分为:主视图(前视图)、后视图、左视图、右视图、俯视图、仰视图。

    但根据机械制图原理,看不见的轮廓用虚线表示,看得见的轮廓用实线表示则可以推断上述视图为两两对应,可以将其中一个删除。因此,六视图就变成了“三视图”,分别保留:主视图、左视图、俯视图,其余视图省略。

    在这里插入图片描述

    在三视图当中,其两两都对应着一种投影规律,掌握这种规律就能保住绘制的三视图不会出现错误。牢记:

    主、俯视图:长对正

    主、左视图:高平齐

    俯、左视图:宽相等

    在这里插入图片描述

    除了视图特性以外,投影也是一个重点,属于概念性的内容,需要多思考、练习。这直接决定了是否能将产品还原与视图表达。

    首先记住投影规律:

    当产品各面与投影面垂直:收缩性

    当产品各面与投影面平行:实形性

    当产品各面与投影面倾斜:类似性

    在这里插入图片描述

    线型表达

    机械制图中常见的线型种类有5种,分别是:虚线、细实线、粗实线、点划线、双点划线。每种线型所表达的意思是不同的。

    虚线:不可见轮廓线

    细实线:尺寸线、尺寸界线、刨面线

    粗实线:可见轮廓线

    点划线:中心线、对称线

    双点划线:假象线

    在这里插入图片描述

    展开全文
  • 学好机械制图,这2个核心要点是关键! 机械制图属于大学机械、工程类必学内容,而且...根据六个不同方向将视图分为:主视图(前视图)、后视图、左视、右视图、俯视、仰视。 但根据机械制图原理,看不见的轮廓用
  • Protell即学即会教程

    2009-07-21 14:10:41
    很多网友渴望自己设计电路原理图(SCH)、电路板(PCB),同时希望从 原始SCH到PCB自动布线、再到成品PCB电路板的设计周期可以缩短到1天以内! 是不是不可能呢?当然不是,因为现在的EDA软件已经达到了几乎...
  • 5天学会protel 99 se

    2010-05-12 14:45:16
    很多网友渴望自己设计电路原理图(SCH)、电路板(PCB),同时希望从原始SCH到PCB自动布线、再到成品PCB电路板的设计周期可以缩短到1天以内!是不是不可能呢?当然不是,因为现在的EDA软件已经达到了几乎无所不能的...
  • 很多网友渴望自己设计电路原理图(SCH)、电路板(PCB),同时希望从原始SCH到PCB自动布线、再到成品PCB电路板的设计周期可以缩短到1天以内!是不是不可能呢?当然不是,因为现在的EDA软件已经达到了几乎无所不能的...
  • 教程原作者:张晓刚,CHM制作:多啦A梦 很多网友渴望自己设计电路原理图(SCH)、电路板(PCB),同时希望从原始SCH到PCB自动布线、再到成品PCB电路板的设计周期可以缩短到1天以内!是不是不可能呢?当然不是,...

空空如也

空空如也

1 2 3 4 5
收藏数 90
精华内容 36
关键字:

原理图是不是就是工程图