指针指向结构体的问题

时间:2022-04-28 10:43:00
假设X为一结构体变量,已经全部符好值了

它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型


请问:让指针p指到X,直接p=&X
指到a, p=&(X.a)对吗?
指到o, p=&(X.a.o)对吗?
先指到o,再指到p, p==&(X.a.o+1)对吗?
还有o,p,q三个变量是存储在连续的空间吗?

不晓得你们明白意思没有。。。。。

16 个解决方案

#1


我在等各位帅哥们答疑解惑啊。。。。。

#2


额 ,你应该是先定义一个X类型的对象 比如 X obj;  然后才是 p=&obj.a

#3


p = &X;
a_tmp = p->a;
a.o = p->a.o;

#4


首先楼主问的问题可能让人产生疑惑,p是指针还是a中的数据成员。

让指针p指到X,直接p=&X。
//可以,不过p必须声明为指向与X同类型的结构体类型的指针
指到a, p=&(X.a)对吗?
//可以,不过p必须声明为指向与a同类型的结构体类型的指针,不能是前面的p
指到o, p=&(X.a.o)对吗?
//可以,不过p必须声明为指向与o同类型的指针,不能是前面的p
先指到o,再指到p, p==&(X.a.o+1)对吗?
//这个应该不对
还有o,p,q三个变量是存储在连续的空间吗?
//这个不一定,涉及到结构体的对齐

#5


贴个小例子


#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
    char  o;
    short p;
    int   q;
}TA;

typedef struct tagX
{
    TA    a;
    char  b;
    short c;
    int   d;
}TX;

int main(void)
{
    void *pvTmp = NULL;
    int aa;
    TX   tTest = {'a', 1, 2, 'b', 3, 4};

    pvTmp = &tTest;         // 让指针pvTmp指到tTest
    pvTmp = &(tTest.a);     // 指到a
    pvTmp = &(tTest.a.o);   // 指到o
    pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o);   // 先指到o,再指到p

    return 0;
}

#6


指针是一种复合数据类型,它依赖于跟它类型相同的变量而存在,比如double *p那么p通常就指向doule型的变量,int *p通常就指针int型的变量,这里说的是通常,因为还存在强制转换

#7


对的,但是结构体在内存中的存储是有一定的对齐方式的,具体的对齐方式与编译器有关,在没有人为干扰的情况下,有下面的对齐原则:
(1) 首先, 假设结构的起始地址为 0x00000000.
(2) 第二, 每个成员变量以其自身类型占用的空间大小进行对齐, 例如 char 类型按1对齐, short int 类型按 2 对齐, int 类型按 3 对齐等等.
(3) 第三, 结构体按照其成员中对齐数最大的成员进行对齐.
可以自己写个小程序试试很容易验证

#8


该回复于2011-03-21 09:25:26被版主删除

#9


该回复于2011-03-21 08:58:35被版主删除

#10


感觉.多了容易糊涂,建议用->

#11


引用 5 楼 jernymy 的回复:
贴个小例子


C/C++ code

#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
    char  o;
    short p;
    int   q;
}TA;

……




1,pvTmp = &tTest; 是否应该改为pvTmp = (TX *)&tTest;
2,    pvTmp = &(tTest.a);   是否应该改为   pvTmp = (TA *)&(tTest.a);   
    pvTmp = &(tTest.a.o);  是否应该改为pvTmp = (char *)&(tTest.a.o);  
3,pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o); 先指到O为char型,然后指针向后移指到p为short型,指针的类型发生改变了,请问是否存在问题?是否应该改成:
pvTmp = (short *)( &(tTest.a.o) + sizeof(tTest.a.o) );
            

#12


对不对?

#13


结构体里面的变量不是连续存储的....

#14


有时可能需要‘强制类型转换’一下

#15


主要是你定义的指针P的类型要和你所需指向的对象的类型匹配,有时可以用void *,但是空指针不能引用你所指向的内存的内容,如果要这样做,一般可以强制转换一下

#16


引用 11 楼 xitijie 的回复:
引用 5 楼 jernymy 的回复:
贴个小例子


C/C++ code

#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
char o;
short p;
int q;
}T……


您好

1,pvTmp = &tTest; 是否应该改为pvTmp = (TX *)&tTest; 
// 不需要的,因为void *pvTmp 是无类型的指针就是方便可以指向任何类型的地址

2, pvTmp = &(tTest.a); 是否应该改为 pvTmp = (TA *)&(tTest.a); 
// 同1
  pvTmp = &(tTest.a.o); 是否应该改为pvTmp = (char *)&(tTest.a.o);  
// 同1
 
3,pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o); 先指到O为char型,然后指针向后移指到p为short型,指针的类型发生改变了,请问是否存在问题?是否应该改成:
pvTmp = (short *)( &(tTest.a.o) + sizeof(tTest.a.o) );
// 同1,因为地址的偏移已经计算好了。
使用void类型指针的好处,就是可以指向任何类型的指针,不需要强转。

#1


我在等各位帅哥们答疑解惑啊。。。。。

#2


额 ,你应该是先定义一个X类型的对象 比如 X obj;  然后才是 p=&obj.a

#3


p = &X;
a_tmp = p->a;
a.o = p->a.o;

#4


首先楼主问的问题可能让人产生疑惑,p是指针还是a中的数据成员。

让指针p指到X,直接p=&X。
//可以,不过p必须声明为指向与X同类型的结构体类型的指针
指到a, p=&(X.a)对吗?
//可以,不过p必须声明为指向与a同类型的结构体类型的指针,不能是前面的p
指到o, p=&(X.a.o)对吗?
//可以,不过p必须声明为指向与o同类型的指针,不能是前面的p
先指到o,再指到p, p==&(X.a.o+1)对吗?
//这个应该不对
还有o,p,q三个变量是存储在连续的空间吗?
//这个不一定,涉及到结构体的对齐

#5


贴个小例子


#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
    char  o;
    short p;
    int   q;
}TA;

typedef struct tagX
{
    TA    a;
    char  b;
    short c;
    int   d;
}TX;

int main(void)
{
    void *pvTmp = NULL;
    int aa;
    TX   tTest = {'a', 1, 2, 'b', 3, 4};

    pvTmp = &tTest;         // 让指针pvTmp指到tTest
    pvTmp = &(tTest.a);     // 指到a
    pvTmp = &(tTest.a.o);   // 指到o
    pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o);   // 先指到o,再指到p

    return 0;
}

#6


指针是一种复合数据类型,它依赖于跟它类型相同的变量而存在,比如double *p那么p通常就指向doule型的变量,int *p通常就指针int型的变量,这里说的是通常,因为还存在强制转换

#7


对的,但是结构体在内存中的存储是有一定的对齐方式的,具体的对齐方式与编译器有关,在没有人为干扰的情况下,有下面的对齐原则:
(1) 首先, 假设结构的起始地址为 0x00000000.
(2) 第二, 每个成员变量以其自身类型占用的空间大小进行对齐, 例如 char 类型按1对齐, short int 类型按 2 对齐, int 类型按 3 对齐等等.
(3) 第三, 结构体按照其成员中对齐数最大的成员进行对齐.
可以自己写个小程序试试很容易验证

#8


该回复于2011-03-21 09:25:26被版主删除

#9


该回复于2011-03-21 08:58:35被版主删除

#10


感觉.多了容易糊涂,建议用->

#11


引用 5 楼 jernymy 的回复:
贴个小例子


C/C++ code

#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
    char  o;
    short p;
    int   q;
}TA;

……




1,pvTmp = &tTest; 是否应该改为pvTmp = (TX *)&tTest;
2,    pvTmp = &(tTest.a);   是否应该改为   pvTmp = (TA *)&(tTest.a);   
    pvTmp = &(tTest.a.o);  是否应该改为pvTmp = (char *)&(tTest.a.o);  
3,pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o); 先指到O为char型,然后指针向后移指到p为short型,指针的类型发生改变了,请问是否存在问题?是否应该改成:
pvTmp = (short *)( &(tTest.a.o) + sizeof(tTest.a.o) );
            

#12


对不对?

#13


结构体里面的变量不是连续存储的....

#14


有时可能需要‘强制类型转换’一下

#15


主要是你定义的指针P的类型要和你所需指向的对象的类型匹配,有时可以用void *,但是空指针不能引用你所指向的内存的内容,如果要这样做,一般可以强制转换一下

#16


引用 11 楼 xitijie 的回复:
引用 5 楼 jernymy 的回复:
贴个小例子


C/C++ code

#include "stdio.h"
/*
假设X为一结构体变量,已经全部符好值了
它包含a,b,c,d 四种不同的数据类型
而a又是一个结构体变量,其包含o,p,q三个数据类型
*/

typedef struct tagA
{
char o;
short p;
int q;
}T……


您好

1,pvTmp = &tTest; 是否应该改为pvTmp = (TX *)&tTest; 
// 不需要的,因为void *pvTmp 是无类型的指针就是方便可以指向任何类型的地址

2, pvTmp = &(tTest.a); 是否应该改为 pvTmp = (TA *)&(tTest.a); 
// 同1
  pvTmp = &(tTest.a.o); 是否应该改为pvTmp = (char *)&(tTest.a.o);  
// 同1
 
3,pvTmp = (unsigned char *)&(tTest.a.o) + sizeof(tTest.a.o); 先指到O为char型,然后指针向后移指到p为short型,指针的类型发生改变了,请问是否存在问题?是否应该改成:
pvTmp = (short *)( &(tTest.a.o) + sizeof(tTest.a.o) );
// 同1,因为地址的偏移已经计算好了。
使用void类型指针的好处,就是可以指向任何类型的指针,不需要强转。