首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

结构体二维数组指针有关问题!

2013-01-23 
结构体二维数组指针问题!!!1.定义一个结构体,里面是两个unsigned char: (图1)2.定义一张表,是该结构体的二

结构体二维数组指针问题!!!
1.定义一个结构体,里面是两个unsigned char: (图1)
结构体二维数组指针有关问题!
2.定义一张表,是该结构体的二维数组,里面是10x10个TblCalc(图2)
结构体二维数组指针有关问题!
3.定义一个表数组,里面存放多张2中定义的表
结构体二维数组指针有关问题!

现在我想取数据g_tbl_calc_10[0][8][1],图2中的蓝色部分

程序运行中内存分布如图(vs2008):
结构体二维数组指针有关问题!

TblCalc *tbl_add;
tbl_add = &g_tbl_calc_10[enOpt - OPT_ADD][a][b]; 
tbl_add = (TblCalc *)((char *)*g_tbl_calc_10[enOpt-OPT_ADD] + (a * 10 + b) * sizeof(TblCalc));
两种方法取到的值都是:0x0041da5a ,这个指针指哪去了?

最让我奇怪的是,我在vs里,直接观察 (TblCalc *)((char *)*g_tbl_calc_10[enOpt-OPT_ADD] + (a * 10 + b) * sizeof(TblCalc)),是我想要的{ 0, 9 }结点:
结构体二维数组指针有关问题!
但是,tbl_add = (TblCalc *)((char *)...付完值却始终是0x0041da5a 
结构体二维数组指针有关问题!

还有,试过直接取内存数据TblCalc.cLow :
char ch = ((TblCalc *)((char *)g_tbl_calc_10[enOpt-OPT_ADD] + (a * 10 + b) * sizeof(TblCalc)))->cLow;
内存里直接观察为:0x09,取出来确是0x02!!(0x0041da5a 指向的那个结点)
结构体二维数组指针有关问题!

困扰我好几天了,哪位高手来帮我分析一下啊!!
这几次取值出现这种现象原因是什么?正确应该怎么个取法?

[解决办法]
TblCalc (*g_tbl_calc_10)[10][10] = ......................
g_tbl_calc_10不要写成g_tbl_calc_10[]
[解决办法]
你在百度知道里问的问题,我的回答被度娘吞了,再在这里回答吧。
你定义数组的方法太让人头大了。适当用下typedef,能更容易理解。

#include<stdio.h>

typedef unsigned int UCHAR;

typedef struct
{
UCHAR cHigh;
UCHAR cLow;
}TblCalc;

TblCalc g_tbl_add_10[10][10]={
    {{0,0},{0,1},{0,2},{0,3},{0,4},{0,5},{0,6},{0,7},{0,8},{0,9}},
    {{1,0},{1,1},{1,2},{1,3},{1,4},{1,5},{1,6},{1,7},{1,8},{1,9}},
    {{2,0},{2,1},{2,2},{2,3},{2,4},{2,5},{2,6},{2,7},{2,8},{2,9}},
    {{3,0},{3,1},{3,2},{3,3},{3,4},{3,5},{3,6},{3,7},{3,8},{3,9}},
    {{4,0},{4,1},{4,2},{4,3},{4,4},{4,5},{4,6},{4,7},{4,8},{4,9}},
    {{5,0},{5,1},{5,2},{5,3},{5,4},{5,5},{5,6},{5,7},{5,8},{5,9}},
    {{6,0},{6,1},{6,2},{6,3},{6,4},{6,5},{6,6},{6,7},{6,8},{6,9}},
    {{7,0},{7,1},{7,2},{7,3},{7,4},{7,5},{7,6},{7,7},{7,8},{7,9}},
    {{8,0},{8,1},{8,2},{8,3},{8,4},{8,5},{8,6},{8,7},{8,8},{8,9}},
    {{9,0},{9,1},{9,2},{9,3},{9,4},{9,5},{9,6},{9,7},{9,8},{9,9}},
};

TblCalc g_tbl_sub_10[10][10]={
    0
};

typedef TblCalc (*PTbl)[10][10];

PTbl g_tbl_calc_10[] = 
{
&g_tbl_add_10, &g_tbl_sub_10
};

void main(void)
{
printf("%d %d\n", (*g_tbl_calc_10[0])[8][1].cHigh, (*g_tbl_calc_10[0])[8][1].cLow);
}


[解决办法]
TblCalc *tbl_add;
tbl_add = &g_tbl_calc_10[enOpt - OPT_ADD][a][b]; 
tbl_add = (TblCalc *)((char *)*g_tbl_calc_10[enOpt-OPT_ADD] + (a * 10 + b) * sizeof(TblCalc));


两种方法取到的值都是:0x0041da5a ,这个指针指哪去了?



改爲下面的看看:

TblCalc *tbl_add;
tbl_add = &(*g_tbl_calc_10[enOpt - OPT_ADD])[a][b]; 


[解决办法]
你的变量声明:
TblCalc (*g_tbl_calc10[])[10][10] = 
{
&g_tbl_add_10,
&g_tbl_sub_10
};

不知道是什么风格。不太常见,也不好理解。

我理解这个声明的含义:
首先,g_tbl_calc10是一个数组。因为[]的优先级比*要高。
其次,数组的每一个元素是一个指针。
再次,这个指针的类型是:TblCalc[10][10]。不妨把这个类型简称为T。

所以,g_tbl_calc[0][8][1]的含义可以按以下顺序理解:
1,首先看g_tbl_calc[0]。它是指针数组的第一个元素,它本身是一个指针,指向g_tbl_add_10;
它所指向的对象的大小为sizeof(g_tbl_add_10)=sizeof(T)=200=0xC8。
2,再来看g_tbl_calc[0][8]。分析它之前先来分析g_tbl_calc[0][0]。
显然它的值和g_tbl_calc[0]是相等的。
由于g_tbl_calc[0]的类型是T的指针,所以g_tbl_calc[0][0]的类型就是T。
所以g_tbl_calc[0][8]和g_tbl_calc[0][0]在空间上就相差8个T。

这一点很重要,可以这样类比:
    int a[10];
    a[8]和a[0]都是int类型,其空间上就相差8个sizeof(int)。

因此,g_tbl_calc[0][8] 的地址等于g_tbl_calc[0][0]的地址加上8 * 200!
结构体二维数组指针有关问题!


它相当于指向了g_tbl_calc[0][0]后面的第8个二维数组。

热点排行