快速将一段内存地址转换为我们想要的二维数组的格式

这段时间移植一个图像处理的程序,以前写的时候数据源为二维数组的格式,移植到新的平台上后,图片数据源为一段内存起始地址,就想着怎么在不改变后面所有计算程序的前提下,快速做一个转换。

后面就想到定义一个指针数组来实现:

如:rgb565图片的分辨率是640*480,定义一个480个指针的数组,

unsigned short *data;//图片数组起始地址

unsigned short *rgb_data[480]; //定义一个指针数组

然后个指针数组赋值:

for(i=0;i<480;i++)
    rgb_data[i]= &(data[640*i]); 

然后,在取图片中某个坐标的元素就可以用二维数组的形式来获取:rgb_data[x][y]。

如:取第100行,第80列的点元素就可以表示为rgb_data[100][80]。

unsigned short *data;//图片数组起始地址

unsigned short *rgb_data[480]; //定义一个指针数组

//然后个指针数组赋值:

for(i=0;i<480;i++)
    rgb_data[i]= &(data[640*i]); 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
指针数组和数组指针的区别 数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。 如要将二维数组赋给一指针,应这样赋值: int a[3][4]; int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。 p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0] p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][] 所以数组指针也称指向一维数组的指针,亦称行指针。 指针数组 定义 int *p[n]; []优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。 如要将二维数组赋给一指针数组: int *p[3]; int a[3][4]; for(i=0;i<3;i++) p[i]=a[i]; 这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2] 所以要分别赋值。 这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。 还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。 比如要表示数组中i行j列一个元素: *(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j] 就指向指针的指针,很早以前在说指针的时候说过,但后来发现很多人还是比较难以理解,这一次我们再次仔细说一说指向指针的指针。  先看下面的代码,注意看代码中的注解: #include <iostream>  #include <string>  using namespace std;    void print_char(char* array[],int len);//函数原形声明    void main(void)    {  //-----------------------------段1-----------------------------------------      char *a[]={"abc","cde","fgh"};//字符指针数组      char* *b=a;//定义一个指向指针的指针,并赋予指针数组首地址所指向的第一个字符串的地址也就是abc\0字符串的首地址      cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;  //-------------------------------------------------------------------------    //-----------------------------段2-----------------------------------------      char* test[]={"abc","cde","fgh"};//注意这里是引号,表示是字符串,以后的地址每加1就是加4位(在32位系统上)      int num=sizeof(test)/sizeof(char*);//计算字符串个数      print_char(test,num);      cin.get();  //-------------------------------------------------------------------------  }    void print_char(char* array[],int len)//当调用的时候传递进来的不是数组,而是字符指针他每加1也就是加上sizeof(char*)的长度  {      for(int i=0;i<len;i++)      {          cout<<*array++<<endl;      }  }   下面我们来仔细说明一下字符指针数组和指向指针的指针,段1中的程序是下面的样子: char *a[]={"abc","cde","fgh"};  char* *b=a;  cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;   char *a[]定义了一个指针数组,注意不是char[], char[]是不能同时初始化为三个字符的,定义以后的a[]其实内部有三个内存位置,分别存储了abc\0,cde\0,fgh\0,三个字符串的起始地址,而这三个位置的内存地址却不是这三个字符串的起始地址,在这个例子中a[]是存储在栈空间内的,而三个字符串却是存储在静态内存空间内的const区域中的,接下去我们看到了char* *b=a;这里是定义了一个指向指针的指针,如果你写成char *b=a;那么是错误的,因为编译器会返回一个无法将char* *[3]转换给char *的错误,b=a的赋值,实际上是把a的首地址赋给了b,由于b是一个指向指针的指针,程序的输出cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<<endl;   结果是 abc cde fgh   可以看出每一次内存地址的+1操作事实上是一次加sizeof(char*)的操作,我们在32位的系统中sizeof(char*)的长度是4,所以每加1也就是+4,实际上是*a[]内部三个位置的+1,所以*(b+1)的结果自然就是cde了,我们这时候可能会问,为什么输出是cde而不是c一个呢?答案是这样的,在c++中,输出字符指针就是输出字符串,程序会自动在遇到\0后停止.   我们最后分析一下段2中的代码,段2中我们调用了print_array()这个函数,这个函数中形式参数是char *array[]和代码中的char *test[]一样,同为字符指针,当你把参数传递过来的时候,事实上不是把数组内容传递过来,test的首地址传递了进来,由于array是指针,所以在内存中它在栈区,具有变量一样的性质,可以为左值,所以我们输出写成了,cout<<*array++<<endl;当然我们也可以改写为cout<<array[i]<<endl,这里在循环中的每次加1操作和段1代码总的道理是一样的,注意看下面的图!   到这里这两个非常重要的知识点我们都说完了,说归说,要想透彻理解希望读者多动手,多观察,熟能生巧。   下面是内存结构示意图:
1. 算法的基本概念 利用计算机算法为计算机解题的过程实际上是在实施某种算法。 (1)算法的基本特征 算法一般具有4个基本特征:可行性、确定性、有穷性、拥有足够的情报。 (2)算法的基本运算和操作 算法的基本运算和操作包括:算术运算、逻辑运算、关系运算、数据传输。 (3)算法的3种基本控制结构 算法的3种基本控制结构是:顺序结构、选择结构、循环结构。 (4)算法基本设计方法 算法基本设计方法:列举法、归纳法、递推、递归、减半递推技术、回溯法。 (5)指令系统 所谓指令系统指的是一个计算机系统能执行的所有指令的集合。 (2)数据结构研究的3个方面 ① 数据集合中各数据元素之间所固有的逻辑关系,即数据的逻辑结构; ② 在对数据进行处理时,各数据元素在计算机中的存储关系,即数据的存储结构; ③ 对各种数据结构进行的运算。 2. 逻辑结构 数据的逻辑结构是对数据元素之间的逻辑关系的描述,它可以用一个数据元素的集合和定义在此集合中的若干关系来表示。数据的逻辑结构有两个要素:一是数据元素的集合,通常记为D;二是D上的关系,它反映了数据元素之间的前后件关系,通常记为R。一个数据结构可以表示成:B=(D,R) 其中,B表示数据结构。为了反映D中各数据元素之间的前后件关系,一般用二元组来表示。 例如,如果把一年四季看作一个数据结构,则可表示成:B =(D,R) D ={春季,夏季,秋季,冬季} R ={(春季,夏季),(夏季,秋季),(秋季,冬季)} 3. 存储结构 数据的逻辑结构在计算机存储空间中的存放形式称为数据的存储结构(也称数据的物理结构)。 由于数据元素在计算机存储空间中的位置关系可能与逻辑关系不同,因此,为了表示存放在计算机存储空间中的各数据元素之间的逻辑关系(即前后件关系),在数据的存储结构中,不仅要存放各数据元素的信息,还需要存放各数据元素之间的前后件关系的信息。 一种数据的逻辑结构根据需要可以表示成多种存储结构,常用的存储结构有顺序、链接等存储结构。 顺序存储方式主要用于线性的数据结构,它把逻辑上相邻的数据元素存储在物理上相邻的存储单元里,结点之间的关系由存储单元的邻接关系来体现。 链式存储结构就是在每个结点中至少包含一个指针域,用指针来体现数据元素之间逻辑上的联系。 1.2.2 线性结构和非线性结构 根据数据结构中各数据元素之间前后件关系的复杂程度,一般将数据结构分为两大类型:线性结构与非线性结构。 (1)如果一个非空的数据结构满足下列两个条件: ① 有且只有一个根结点; ② 每一个结点最多有一个前件,也最多有一个后件。 则称该数据结构为线性结构。线性结构又称线性表。在一个线性结构中插入或删除任何一个结点后还应是线性结构。栈、队列、串等都为线性结构。 如果一个数据结构不是线性结构,则称之为非线性结构。数组、广义表、树和图等数据结构都是非线性结构。 (2)线性表的顺序存储结构具有以下两个基本特点: ① 线性表中所有元素所占的存储空间是连续的; ② 线性表中各数据元素在存储空间中是按逻辑顺序依次存放的。 元素ai的存储地址为:ADR(ai)=ADR(a1)+(i-1)k,ADR(a1)为第一个元素的地址,k代表每个元素占的字节数。 (3)顺序表的运算有查找、插入、删除3种。 1.3 栈 1. 栈的基本概念 栈(stack)是一种特殊的线性表,是限定只在一端进行插入与删除的线性表。 在栈中,一端是封闭的,既不允许进行插入元素,也不允许删除元素;另一端是开口的,允许插入和删除元素。通常称插入、删除的这一端为栈顶,另一端为栈底。当表中没有元素时称为空栈。栈顶元素总是最后被插入的元素,从而也是最先被删除的元素;栈底元素总是最先被插入的元素,从而也是最后才能被删除的元素。 栈是按照“先进后出”或“后进先出”的原则组织数据的。例如,枪械的子弹匣就可以用来形象的表示栈结构。子弹匣的一端是完全封闭的,最后被压入弹匣的子弹总是最先被弹出,而最先被压入的子弹最后才能被弹出。 二级公共基础知识速学教程 2. 栈的顺序存储及其运算 栈的基本运算有3种:入栈、退栈与读栈顶元素。 ① 入栈运算:在栈顶位置插入一个新元素; ② 退栈运算:取出栈顶元素并赋给一个指定的变量; ③ 读栈顶元素:将栈顶元素赋给一个指定的变量。 1.4 队列 1. 队列的基本概念 队列是只允许在一端进行删除,在另一端进行插入的顺序表,通常将允许删除的这一端称为队头,允许插入的这一端称为队尾。当表中没有元素时称为空队列。 队列的修改是依照先进先出的原则进行的,因此队列也称为先进先出的线性表,或者后进后出的线性表。例如:火车进遂道,最先进遂道的是火车头,最后是火车尾,而火车出遂道的时候也是火车头先出,最后出的是火车尾。若有队列: Q =(q1,q2,…,qn) 那么,q1为队头元素(排头
 语言为C#编写,适用于“大智慧新一代 Level-2 V3.03.08.0801 ”的版本。估计分析家6.0的版本也适用,暂没测试过。   对于一些有独特的行情分析方法并且现有的股票分析软件又不能满足的人士,可以考虑采用该数据接口进行二次开发。 组件方法和属性说明:  (1)方法GetData 语法: public string[,] GetData(string dataType, string code,int iRecordCount) 或 public string[,] GetData(string dataType, string code, string newFileName,int iRecordCount) 功能:读取各类数据 参数说明: ?dataType为数据类型,目录允许的值如下: “dm”——代码表,对应大智慧文件STKINFO60.DAT “hq”——日行情,对应大智慧文件day.dat “hqmb”——每笔成交,对应大智慧文件report.dat或*.prp “hq0”——最新行情,对应大智慧文件STKINFO60.DAT “hq0_ag”——上海、深圳A股市场动态行情,对应大智慧文件STKINFO60.DAT “hq5”——五分钟线,对应大智慧文件min.dat “cq”——除权数据,对应大智慧文件STKINFO60.DAT “cw0”——专业财务数据,对应大智慧文件STKINFO60.DAT “hqfq”——复权行情。复权计算方法与一般行情软件有所不同:只对日线数据中的开盘价、最高价、最低价、收盘价进行复权处理,成交量未作复权处理;先根据价格和除权数据计算出每日总收益率,然后用“向前复权”方法计算出复权价格(优点是:假设了分红再投资,任何两点间的收益率不受分红送配时间的影响,便于分析比较);提供根据收盘价计算的收益率。  ?code为证券代码,格式如“SH000001”、“SZ000001”、“HK0001”等,其中板块指数的代码如“$$AA01”、“$$AA02”等;当dataType为“dm”或”hq0”时,为市场代码“SH”或“SZ”等,板块指数的市场代码为“$$”。 如: GetData("hq","SZ399001")读取SZ399001(深成指)的所有行情数据; GetData("hq","$$AA01")读取板块指数$$AA01行情; GetData(“dm”,”SH”)读取沪市证券代码表; GetData(“hq0”,”SH”)读取沪市股票的动态行情; GetData(“hq_ag”,””)读取沪市和深市股票的动态行情。 ?newFileName为不含路径的文件名,例如:读取沪市代码表时默认从大智慧目录安装目录下的DATA\SH\StkInfo60.dat文件中读取,但可以指定从其它文件读取,如GetData(“dm”,”SH”,”stkinfo88888.dat”)将从stkinfo8888.dat文件读取代码表(当然前提是该文件结构与stkinfo60.dat相同)。该功能主要用于读取历史分笔数据,如GetData(“hqmb”,”SZ000001”,”20080926.PRP”)将读取深发展2008年9月26日的分笔成交数据。 ?newFileName为读取的行情记录的数量。为0则读取所有记录。 如: GetData("hq","SH600000",0)读取SH600000(浦发银行)的所有日行情数据; GetData("hq","SH600000",10)读取SH600000(浦发银行)的最后10日行情数据。 返回值:返回一个二维字符串数组,每一列为一字段,每一行为一数据记录。注意,这里返回的是一个字符串数组,一般需要根据需要类型转换。 (2)方法GetFields 语法:public string[,] GetFields(string dataType) 功能:读取各种数据类型的字段名、字段含义、类型。 参数说明:dataType为指定数据类型同GetData。 返回值:一个二维数组 (3)方法GetTables 调用格式:public string[,] GetTables() 功能:读取各表的表名、中文说明、对应文件。 返回值:一个二维数组 (4)方法GetMarkets 语法:public string[,] GetMarkets() 功能:从注册表中读取市场列表:代码、简称、名称,如:SH、沪、上海证券交易所;SZ、深、深圳证券交易所。 返回值:一个二维数组 (5)方法GetTableDef 语法:public string GetTableDef(string dataType, string descDataType, bool delOldTable) 功能:生成创建SAS表的PROC SQL语句。 参数:dataType为“dm”等数据表名,descDataType目前只能为“SAS”,delOldTable是否同时生成删除同名数据表的语句。 返回值:一个字符串 (6)方法GetCodeType 语法:public string GetCodeType(string code) 功能:根据证券代码获取证券品种,如:GetCodeType("SZ000001")将返回"gp"表示这是股票代码;GetCodeType("SH000001")将返回"zs”(指数);GetCodeType("SZ184688")将返回"jj"(基金),等。 参数:code为证券代码。 返回值:一个字符串:gp(股票)、zq(债券)、jj(基金)、qz(权证)、zs(指数)。 (7)方法ShowAboutBox 语法:public void ShowAboutBox() 功能:显示组件的“关于”窗口。 (8)方法ShowFxjConverter 语法:public void ShowFxjConverter() 功能:显示“大智慧数据转换器”窗口。可以读取各类数据,不过一般每次只能读取一只证券的数据;可以读取各字段信息;可以将读取出来的数据保存为文本文件。 (9)方法ShowFxjReader 语法:public void ShowFxjReader() 功能:显示“大智慧数据读取器”窗口。可以将各类数据转换为文本文件,字段间的分隔符可以自定义; (10)属性FxjDataPath 功能:字符串型,可读写,返回大智慧数据目录(一般为c:\dzh\data\),如果组件无法自动获取正确的大智慧数据目录,可以设置该属性指定大智慧数据目录。 (11)属性FxjPath 功能:字符串型,返回大智慧安装目录(一般为c:\dzh\)。 (12)属性Error 功能:整型,只读,返回上一步操作是否出现错误。若该属性为0,表示没有错误发生,若为1则表示发生了错误,具体错误信息可以通过MSG属性获得。 (13)属性Msg 功能:字符串型,只读,返回上一步操作的错误信息。 (14)属性Version 功能:实型,返回组件当前版本号

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值