阶段性研究

变量存储区域问题

先上结论:

static无论是全局变量还是局部变量都存储在全局/静态区域,在编译期就为其分配内存,在程序结束时释放,例如:val_a、val_d、val_h、val_i。

const全局变量存储在只读数据段,编译期最初将其保存在符号表中,第一次使用时为其分配内存,在程序结束时释放,例如:val_c;const局部变量存储在栈中,代码块结束时释放,例如:val_j。

全局变量存储在全局/静态区域,在编译期为其分配内存,在程序结束时释放,例如:val_b、val_e。

局部变量存储在栈中,代码块结束时释放,例如:val_h、val_i。

注:当全局变量和静态局部变量未赋初值时,系统自动置为0。

为了验证各类数据所在的数据段,实现了一个简易的内存显示单元mem.h

//mem.h
#ifndef __MEM_H
#define __MEM_H
#include <stdio.h>

void display(void *srcptr);

#include "mem.c"
#endif
//mem.c
void display(void *srcptr){
	char *p, *pos;
	for (pos = (char *)((unsigned int)srcptr & 0xFFFFFFF0);
		pos < srcptr + 0x80; pos += 0x10){
		printf("%06X:  ", pos);
		for (p = pos; p < pos + 16; ++p){
			if (p < srcptr || p >= srcptr + 0x80)
				printf("   ");
			else if (p == pos + 7)
				printf("%02X-", *p & 0xFF);
			else
				printf("%02X ", *p & 0xFF);
		}
		printf("  ");
		for (p = pos; p < pos + 16; ++p){
			if (p < srcptr || p >= srcptr + 0x80)
				putchar(‘ ‘);
			else if (*p < 0x80 && *p >= 0x20)
				putchar(*p & 0xFF);
			else
				putchar(‘.‘);
		}
		putchar(‘\n‘);
	}
	putchar(‘\n‘);
}

测试例程和结果如图:

全局变量,const全局变量,局部变量,const局部变量的存储:

常指针表示的字符串常量:

数组表示的字符串常量:

现在我们发现字符串常量用数组和常指针表示的内存分配情况有很大差异。

函数调用栈中无维数数组形参的传递:

const变量是否在第一次引用时分配内存

一直认为const变量是与同作用域的变量共同存在的,写程序验证如下:

虽未引用b和d,但显然为其分配了内存,仿佛与上面说法相悖,不妨开-O优化试试:

结果可喜可贺,未引用的const变量没有分配内存。以上程序经gcc/g++分别测试,结果相同。

const变量是否真正不可修改

尝试用指针修改const全局变量和const局部变量,做如下两组试验:

尝试修改const局部变量:

解释:const局部变量在栈中,无法保证其值不被修改,但为什么第二次输出a是5而不是2呢?

作如下试验程序:

int A, B;
int main(){
	const int a = 5;
	int * p = (int *)&a;
	*p = 2;
	A = *p;
	B = a;
}

用GDB查看汇编代码如下:

   //a = 5;
   0x004013c8 <+24>:	mov    DWORD PTR [esp+0x8],0x5
   //p = (int *)&a;
   0x004013d0 <+32>:	lea    eax,[esp+0x8]
   0x004013d4 <+36>:	mov    DWORD PTR [esp+0xc],eax
   //*p = 2;
=> 0x004013d8 <+40>:	mov    eax,DWORD PTR [esp+0xc]
   0x004013dc <+44>:	mov    DWORD PTR [eax],0x2
   //A = *p;
   0x004013e2 <+50>:	mov    eax,DWORD PTR [esp+0xc]
   0x004013e6 <+54>:	mov    eax,DWORD PTR [eax]
   0x004013e8 <+56>:	mov    ds:0x406024,eax
   //B = a;
   0x004013ed <+61>:	mov    DWORD PTR ds:0x406028,0x5

于是我们发现,编译器将a作为立即数5写入汇编代码,从而导致引用a值仍为5。

可见const可以保证某个变量是编译时常量。

尝试修改const全局变量:

错误很显然:const全局变量在只读区段,不允许修改。

数组与常指针的差异

一个显而易见的差异是元素大小不同:

sizeof (int [10]) = 10 * sizeof (int);
sizeof (int * const) = sizeof (int *);

它影响到以之为基类的指针寻址:

int (*) [10];
int *const *;

尝试取数组名的地址,得到如下结果:

发现数组名的地址与数组名的值相同,而第一个单元存放的是数组的第一个元素,所以数组名绝不可能是一个指针。

C/C++把数组当作一种独立的数据类型处理。

为什么可以用数组名初始化指针呢?因为初始化发生了从int [N] -> int *的隐式转换。这种隐式转换并不影响用int *p对数组寻址。

用常指针为数组元素寻址与直接用数组寻址的差别:

//global
int array[10] = {0};
int *const parray = array;
//----------------------------------------------------------
   //parray[0] = 1;
   // 指针parray的地址(偏移地址)是编译时常量0x404080
=> 0x0040150b <+21>:	mov    eax,ds:0x404080
   0x00401510 <+26>:	mov    DWORD PTR [eax],0x1
   //array[0] = 1;
   // 数组array的地址(偏移地址)是编译时常量0x406040
   0x00401516 <+32>:	mov    DWORD PTR ds:0x406040,0x1

   //parray[1] = 1;
=> 0x0040150b <+21>:	mov    eax,ds:0x404080
   0x00401510 <+26>:	add    eax,0x4
   0x00401513 <+29>:	mov    DWORD PTR [eax],0x1
   //array[1] = 1;
   0x00401519 <+35>:	mov    DWORD PTR ds:0x406044,0x1

   //int i = 1;
   0x0040150e <+24>:	mov    DWORD PTR [esp+0xc],0x1
   //parray[i] = 1;
=> 0x00401516 <+32>:	mov    eax,ds:0x404080
   0x0040151b <+37>:	mov    edx,DWORD PTR [esp+0xc]
   0x0040151f <+41>:	shl    edx,0x2
   0x00401522 <+44>:	add    eax,edx
   0x00401524 <+46>:	mov    DWORD PTR [eax],0x1
   //array[i] = 1;
   0x0040152a <+52>:	mov    eax,DWORD PTR [esp+0xc]
   0x0040152e <+56>:	mov    DWORD PTR [eax*4+0x406040],0x1

实现完全不同,这再次说明数组是一种独立的数据类型。

时间: 2024-10-10 07:34:27

阶段性研究的相关文章

什么是PMI

项目管理协会 PMI PMI是世界领先的非盈利会员协会的项目管理专业机构 ,在全球185个国家有70多万会员和证书持有人.此外,PMI还是多个英文短语的缩写,较为著名的是采购经理指数PMI. 项目管理协会 PMI(Project Management Institute)成立于1969年,是全球领先的项目管理行业的倡导者,它创造性地制定了行业标准,由PMI组织编写的<项目管理知识体系指南>(PMBoK)已经成为项目管理领域最权威教科书,被誉为项目管理"圣经".PMI目前在全

一文看懂非标业务中的收益权

来源:图解金融 目录 - - - - - 1. 法律法规及监管规范有关“收益权”的规定 2. 非标业务中的收益权交易实践及其法律特征 3. 收益权的法律性质及其交易的法律后果 4. 结语 作者按:自银监会“2013年8号文”首次提出以来,“非标”概念始终在银行业金融监管中扮演着重要角色.2018年颁布的<关于规范金融机构资产管理业务的指导意见>,更将“非标”的适用范围正式扩展至全金融业务领域.究其概念不断发展壮大的原因,“非标”业务在交易主体.交易标的.清算交割.交易信息公开等方面都不受“场内

用户研究:如何了解我们的用户?

一. 前言 来到腾讯以后,做过iPhone阅读器.iPad阅读器.iPad音乐播放器的用户理解,目前正在做iPhone QZone的用户理解工作.做得次数多了,方法在不断改进,也积累了一些经验,与大家一起分享,希望帮助我们更了解用户. 首先介绍一下目前北分wsd(无线研发部用户体验组)用户研究工作流程:我们的用研需求来自项目组和用研组需求池,为控制节奏和质量,对承接项目组需求的工作流程进行严格把控,我们针对项目组需求,制定了用研工作流程图,用户理解也在这个框架之内. 二. 用户理解方法和经验 2

浅谈产业界与学术界的合作研究(转)

[编者注:原文可参阅: http://blog.sciencenet.cn/blog-414166-795432.html ] 最近网络上有一个流传甚广的微故事:"某企业引进了一条香皂包装线,结果发现经常会有空盒流过.厂长聘请一个博士后花了200 万设计出一个全自动分检系统.一个乡镇企业遇到了同样的问题,民工花90 元买了一台大电扇放在生产线旁,一有空盒经过便会吹走."这个微故事不断出现在笔者的视线中,想必在网络上得到了公众的认可.引起了共鸣,所以大家争相转发.平心而论,大多数人的内心

研究一家公司 z

第一部分:确定一家公司的"质地"(描绘一家公司的总体印象)              1.1 天花板       天花板是指企业或行业的产品(或服务)趋于饱和.达到或接近供大于求的状态.在进行投资之前,我们必须明确企业属于下列哪一种情况,并针对不同情况给出相应的投资策略.在判断上,既要重视行业前景,也必须关注企业素质.              1) 已经达到天花板的行业--极度饱和的行业(如钢铁行业).投资机会来自于具有垄断经营能力的企业低成本兼并劣势企业,扩大市场份额,降低产品生产

第一阶段研究工作总结

从三月十五号到今天过去了两个工作日.当初的研究任务主要有三项:液位测量确定软件程序设计.声源定位dsp开发板制版.调试液晶和触摸屏板. 第一个周的工作很顺利.各项进展同步,液位测量程序设计有序进行,并进行了阶段性的数据信号测量:dsp开发板原理图设计,包括电源设计,音频处理电路设计,dsp配置调试电路,sdram数据存储电路设计,以及串口通信接口设计.lcd液晶屏显示调试顺利完成. 但后来由于avrjtag ice仿真器损坏,液位测量程序设计任务被迫中断,还好经过多天研究,找资料,成功的修好了仿

楼市仅是阶段性回暖 去库存仍是明年楼市主基调

楼市仅是阶段性回暖 去库存仍是明年楼市主基调 行业动态中国证券报[微博]费杨生2014-11-14 01:20 我要分享 1 [摘要]区域上,一线城市回暖迹象更为明显,二三线城市楼市销售仍较清淡:产品上,保障房.自住型商品房成为部分地区楼市成交主力,商品住宅成交仍处历史低位. 在调控政策去行政化.成交量环比回升的推动下,房地产市场的悲观预期有所减弱,部分房企甚至断言“冬去春又来”.不过,楼市阶段回暖并不代表本轮调整的结束,在经济增速中枢下移.结构调整阵痛犹存的大背景下,应特别警惕楼市衰退的冲击波

unity游戏开发之如何通过用户研究帮助手游产品成功?

狗刨学习网报道 / 2月5日,腾讯IEG市场专业性传播媒体沟通会在深圳召开.腾讯互娱市场部用户研究团队负责人吕品现场分享了腾讯的用户研究团队是如何为端游.手游做用户研究分析的. 腾讯互娱2011年1月成立市场与用户研究中心,2015年调研接触用户次数达到了千万级,目前支持的产品数量达到了131款,有642个研究项目.吕品现场说道:"市场与用户研究中心整个支撑的业务包含了PC游戏.移动游戏和泛娱乐业务,另外我们会做一些基础研究和一些新业务的搜索.我们的用户量级与一家一线研究公司的规模相当.&quo

5分天注定,4分靠打拼:量化研究幸福的6+4本书

5分天注定,4分靠打拼:量化研究幸福的6+4本书 几年看过的量化研究幸福的书.<情绪>是新增的. 这10本书,有6本是严肃的心理学研究的综述或科普.此外,<情绪>主题不全是研究幸福,书中提出,高情绪粒度的人更幸福,有一些方法可以提高情绪粒度,作者认为法官应该提高情绪粒度来提高判案水平.<你要如何衡量你的人生>也是偏理性的视角,因此也放到这个书单中.<为何要提升员工的幸福感>仅仅是哈佛商业评论的4篇文章的合集,<哈佛商业评论>2019年第6期是杂志