浅谈C语言2级指针的简单应用
2010-12-22 13:57
369 查看
在C语言中二级指针是个很有用的东东。有时候在一些性能方面需做平衡且需要灵活性的时候,2级指针就非常有用。
例如在设计UI列表框的时候,我们如果要显示列表框的文本,WINDOWS编程,如果是用一般的GDI函数绘制文本比较慢。微软DX提供了一些方便使用的绘制文本函数,当然这些绘制文本函数不能解决裁剪问题。例如列表框中由于文字过多出现滚动条的时候,那么列表框只能显示其中部分文字,这时候只能自己想办法解决问题了,目前考虑到比较好的方案就是用2级指针。当然想追求速度可以用数组,例如可以为列表框每行文字数量设置一个固定值,然后简单用静态数组为列表框每行文本分配内存最快解决问题,而且高效。但是实在无法忍受其对内存所造成的浪费,当系统有很多列表框而列表框文字又参差不齐的时候更是不能忍受。这时候用2级指针感觉更好。
我在用DX做UI的时候,为了效率,我把整个菜单系统能显示的文本部分全部保存在一个静态字符数组区域。而在这个区域又可划分很多不同的“字符串块”,例如UI的某个文本框所指向的字符为一个字符串块,某个列表框显示的文本为一个字符串块。接下来在给列表框设置数据结构的时候分配一个2级指针,2级指针的好处就是灵活方便且不会造成内存浪费,可以为列表框显示的每行文本提供一个1级指针用于指向列表框每行显示的第1个字的开头位置地址,这样做的好处,就是当移动滚动条的时候直接用移动指针的方法处理文字绘图裁剪问题,而且2级指针的好处不用为每行要绘制的文本分配多余的内存,在遇见列表框每行文字特别参差不齐的时候,其体现得更好。
例如在定义列表框数据的时候可以:
struct LIST_BOX
{
WCHAR *pTextStartPointer; // 文本框指向其文本框对应字符串块的最起始地址
WCHAR **ppListBoxText; // 可用于保存文本框每行文字第1个字符的地址
WCHAR *pPTTextShowLine_1; // 文本框显示第一行第1个文字的地址
unsigned long LineNumber; // 列表框的总行数
unsigned long SelectReturnValue; // 列表框选择项的返回值
unsigned long MouseInBoxPos; // 鼠标所在列表框位置选项的索引
等等和列表框相关数据
…………
…………
…………
};
LIST_BOX *gpListBoxUnion; // 声明列表框元素数据的集合
// 初始化2级指针函数:
int InitListBoxPMemey( unsigned int ListBoxIndex, unsigned long LineNum )
{
// 为某个列表框根据列表框字符的行数(即选项数量)分配2级指针内存
( WCHAR ** )( gpListBoxUnion[ListBoxIndex].ppListBoxText ) = ( WCHAR ** )malloc( sizeof( WCHAR** ) * LineNum );
…………
}
接下来在设置列表框字符串数据函数的时候可以:
int SetListBoxText( unsigned int ListBoxIndex, unsigned long LineNum, const WCHAR *pChar, unsigned long TextCharNum )
{
…………
// 根据2级指针把预设置的文本字符赋给到之前提到的静态数组的字符区域中
for( i = 0; i < TextCharNum; i++ )
{
*( *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + i ) = pChar[i];
}
*( *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + TextCharNum + 1 ) = '/n'; // 换行处理
// 获取下行文本字符开头地址以及获得整列表框字符串块的总长度
if( LineNum < gpListBoxUnion[ListBoxIndex].LineNumber - 1 )
{
*( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum + 1 ) = *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + TextCharNum + 2;
}
else
{
gpListBoxUnion[ListBoxIndex].TextLen = *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) - gpListBoxUnion[ListBoxIndex].pTextStartPointer + TextCharNum;
}
…………
return 1;
}
当然还有很多问题,例如必须为每个列表框的*pTextStartPointer; *pPTTextShowLine_1等指针变量赋予一个合法的初始值。用DX渲染文字。等等还有很多细节问题在这里就省略了
例如在设计UI列表框的时候,我们如果要显示列表框的文本,WINDOWS编程,如果是用一般的GDI函数绘制文本比较慢。微软DX提供了一些方便使用的绘制文本函数,当然这些绘制文本函数不能解决裁剪问题。例如列表框中由于文字过多出现滚动条的时候,那么列表框只能显示其中部分文字,这时候只能自己想办法解决问题了,目前考虑到比较好的方案就是用2级指针。当然想追求速度可以用数组,例如可以为列表框每行文字数量设置一个固定值,然后简单用静态数组为列表框每行文本分配内存最快解决问题,而且高效。但是实在无法忍受其对内存所造成的浪费,当系统有很多列表框而列表框文字又参差不齐的时候更是不能忍受。这时候用2级指针感觉更好。
我在用DX做UI的时候,为了效率,我把整个菜单系统能显示的文本部分全部保存在一个静态字符数组区域。而在这个区域又可划分很多不同的“字符串块”,例如UI的某个文本框所指向的字符为一个字符串块,某个列表框显示的文本为一个字符串块。接下来在给列表框设置数据结构的时候分配一个2级指针,2级指针的好处就是灵活方便且不会造成内存浪费,可以为列表框显示的每行文本提供一个1级指针用于指向列表框每行显示的第1个字的开头位置地址,这样做的好处,就是当移动滚动条的时候直接用移动指针的方法处理文字绘图裁剪问题,而且2级指针的好处不用为每行要绘制的文本分配多余的内存,在遇见列表框每行文字特别参差不齐的时候,其体现得更好。
例如在定义列表框数据的时候可以:
struct LIST_BOX
{
WCHAR *pTextStartPointer; // 文本框指向其文本框对应字符串块的最起始地址
WCHAR **ppListBoxText; // 可用于保存文本框每行文字第1个字符的地址
WCHAR *pPTTextShowLine_1; // 文本框显示第一行第1个文字的地址
unsigned long LineNumber; // 列表框的总行数
unsigned long SelectReturnValue; // 列表框选择项的返回值
unsigned long MouseInBoxPos; // 鼠标所在列表框位置选项的索引
等等和列表框相关数据
…………
…………
…………
};
LIST_BOX *gpListBoxUnion; // 声明列表框元素数据的集合
// 初始化2级指针函数:
int InitListBoxPMemey( unsigned int ListBoxIndex, unsigned long LineNum )
{
// 为某个列表框根据列表框字符的行数(即选项数量)分配2级指针内存
( WCHAR ** )( gpListBoxUnion[ListBoxIndex].ppListBoxText ) = ( WCHAR ** )malloc( sizeof( WCHAR** ) * LineNum );
…………
}
接下来在设置列表框字符串数据函数的时候可以:
int SetListBoxText( unsigned int ListBoxIndex, unsigned long LineNum, const WCHAR *pChar, unsigned long TextCharNum )
{
…………
// 根据2级指针把预设置的文本字符赋给到之前提到的静态数组的字符区域中
for( i = 0; i < TextCharNum; i++ )
{
*( *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + i ) = pChar[i];
}
*( *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + TextCharNum + 1 ) = '/n'; // 换行处理
// 获取下行文本字符开头地址以及获得整列表框字符串块的总长度
if( LineNum < gpListBoxUnion[ListBoxIndex].LineNumber - 1 )
{
*( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum + 1 ) = *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) + TextCharNum + 2;
}
else
{
gpListBoxUnion[ListBoxIndex].TextLen = *( gpListBoxUnion[ListBoxIndex].ppListBoxText + LineNum ) - gpListBoxUnion[ListBoxIndex].pTextStartPointer + TextCharNum;
}
…………
return 1;
}
当然还有很多问题,例如必须为每个列表框的*pTextStartPointer; *pPTTextShowLine_1等指针变量赋予一个合法的初始值。用DX渲染文字。等等还有很多细节问题在这里就省略了
相关文章推荐
- C语言指针应用简单实例
- 简单的指针应用 成绩表 c语言
- 浅谈C语言指针的有趣应用(一)
- 【学习ios之路:C语言】①指针及其简单的应用
- c语言,指针,及其应用
- c语言中指针,二维数组,一维数组,指针数组,二级指针,应用
- 浅谈c语言指针精华(有不规范之处)
- 浅谈C语言 extern 指针与数组
- 指针的简单应用
- 浅谈C语言中变量、常量、数组、字符串、指针的地址
- 浅谈简单数论及应用(一)
- c语言实现单链表&二级指针在单链表的应用
- C语言的简单应用(一)
- 一级指针简单应用
- C语言指针应用——内存分配和释放
- OpenJudge百炼-1183-反正切函数的应用-C语言-简单计算
- C语言int类型指针指向char类型变量简单实例
- 第09天C语言(08):指向函数的指针的应用场景
- 简单的Linux扫描仪应用:C语言实现
- C语言进阶之二级指针的应用:重置内存空间大小