struct BTstruct
{
int i;
char *a;
char *b;
};
然后我这样玩:
int main()
{
struct BTstruct *gh;
gh = (struct BTstruct *)malloc(128);
memset(gh,0,128);
gh->i = 8;
gh->a = "aaaa";
gh->b = "bbbb";
printf("%p---%p\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%s---%s\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%d---%d\n",gh->i,*gh);
return 0;
}
这里printf出来的前后值都一样,
我有一点不懂的是这里为什么是*((struct BTstruct *)((char *)gh+8))而不是*((char *)((char *)gh+8))?
我觉得既然以字节为单位走到成员b的位置,b是char型的指针就该是char *啊为什么要用struct BTstruct *才能得到正确的b成员的地址,进而得到b指向的值呢?
忘哪位C大牛能够解答,谢谢!!
14 个解决方案
#1
对于你这种情况,两者是毫无差别的,因为最后%p只要一个指针而已,无论什么类型的指针结果都一样
#2
指针类型 不影响指向的内存区域内容 \(^o^)/~
指针进行移位时 偏移量不一样而已
指针进行移位时 偏移量不一样而已
#3
可怕的写法
printf 确实不认是什么类型的指针
gh->a = "aaaa";
printf 确实不认是什么类型的指针
#4
int main()
{
struct BTstruct *gh;
gh = (struct BTstruct *)malloc(128);
memset(gh,0,128);
gh->i = 8;
gh->a = "aaaa";
gh->b = "bbbb";
printf("%p---%p\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%s---%s\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%d---%d\n",gh->i,*gh);
printf("%p---%p\n",gh->b,*((char *)((char *)gh+8)));
char *p = "bbbb";
printf("%p\n", *p);
printf("*p\n", p);//编译器优化后,p和gh->b一样了
//printf("%s\n", *p);
return 0;
}
对着比较一下吧
//printf("%s\n", *p); 这个就会发生错误了,字符串没法终止,而你本身可以终止,因为有memset
归咎一点, 对什么样的指针就进行什么样的解引用,也就是取几个字节的问题
{
struct BTstruct *gh;
gh = (struct BTstruct *)malloc(128);
memset(gh,0,128);
gh->i = 8;
gh->a = "aaaa";
gh->b = "bbbb";
printf("%p---%p\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%s---%s\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%d---%d\n",gh->i,*gh);
printf("%p---%p\n",gh->b,*((char *)((char *)gh+8)));
char *p = "bbbb";
printf("%p\n", *p);
printf("*p\n", p);//编译器优化后,p和gh->b一样了
//printf("%s\n", *p);
return 0;
}
对着比较一下吧
//printf("%s\n", *p); 这个就会发生错误了,字符串没法终止,而你本身可以终止,因为有memset
归咎一点, 对什么样的指针就进行什么样的解引用,也就是取几个字节的问题
#5
这里涉及到printf函数的使用问题,你的格式串中%p要求printf函数用4个字节去读变量的值,而如果用char *强制转换后相当于只提供了一个字节的值,其他三个字节的值没有提供,当然得不得b的指向了
ps:printf函数仍会读四个字节,但并非原来的四个字节,因为会类型提升,其他三个字节扩充为符号位
#6
无知无畏啊!真是恐怖!
#7
那个位置确实不能用char *代替。举个例子
那a和b的值是一样的么,楼主的2种不同的指针的区别和这里是一样的。
明显,b中,因为char *的存在(char *表示指向的值是一个字节为单位的),导致b只取&str这个地址所指向的数值中的一个字节,而a则是取的4个字节,这就是a和b不同的原因,所以只要将char改为随意一个4字节类型,a和b都是一样的,所以char *改为int *或者long *都是可以的。另外,实验了一下,*(struct *)value和*(int *)value是等效的。
char *str = "abc";
int a = str;
int b = *(char *)(&str);
那a和b的值是一样的么,楼主的2种不同的指针的区别和这里是一样的。
明显,b中,因为char *的存在(char *表示指向的值是一个字节为单位的),导致b只取&str这个地址所指向的数值中的一个字节,而a则是取的4个字节,这就是a和b不同的原因,所以只要将char改为随意一个4字节类型,a和b都是一样的,所以char *改为int *或者long *都是可以的。另外,实验了一下,*(struct *)value和*(int *)value是等效的。
#8
5楼的回答也是正解。
#9
DING
#10
正解!顶!
#11
学了一学期的DOS C就是不行,看不懂...
#12
学下下
#13
看不懂...
#14
我同意你的说法!
#1
对于你这种情况,两者是毫无差别的,因为最后%p只要一个指针而已,无论什么类型的指针结果都一样
#2
指针类型 不影响指向的内存区域内容 \(^o^)/~
指针进行移位时 偏移量不一样而已
指针进行移位时 偏移量不一样而已
#3
可怕的写法
printf 确实不认是什么类型的指针
gh->a = "aaaa";
printf 确实不认是什么类型的指针
#4
int main()
{
struct BTstruct *gh;
gh = (struct BTstruct *)malloc(128);
memset(gh,0,128);
gh->i = 8;
gh->a = "aaaa";
gh->b = "bbbb";
printf("%p---%p\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%s---%s\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%d---%d\n",gh->i,*gh);
printf("%p---%p\n",gh->b,*((char *)((char *)gh+8)));
char *p = "bbbb";
printf("%p\n", *p);
printf("*p\n", p);//编译器优化后,p和gh->b一样了
//printf("%s\n", *p);
return 0;
}
对着比较一下吧
//printf("%s\n", *p); 这个就会发生错误了,字符串没法终止,而你本身可以终止,因为有memset
归咎一点, 对什么样的指针就进行什么样的解引用,也就是取几个字节的问题
{
struct BTstruct *gh;
gh = (struct BTstruct *)malloc(128);
memset(gh,0,128);
gh->i = 8;
gh->a = "aaaa";
gh->b = "bbbb";
printf("%p---%p\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%s---%s\n",gh->b,*((struct BTstruct *)((char *)gh+8)));
printf("%d---%d\n",gh->i,*gh);
printf("%p---%p\n",gh->b,*((char *)((char *)gh+8)));
char *p = "bbbb";
printf("%p\n", *p);
printf("*p\n", p);//编译器优化后,p和gh->b一样了
//printf("%s\n", *p);
return 0;
}
对着比较一下吧
//printf("%s\n", *p); 这个就会发生错误了,字符串没法终止,而你本身可以终止,因为有memset
归咎一点, 对什么样的指针就进行什么样的解引用,也就是取几个字节的问题
#5
这里涉及到printf函数的使用问题,你的格式串中%p要求printf函数用4个字节去读变量的值,而如果用char *强制转换后相当于只提供了一个字节的值,其他三个字节的值没有提供,当然得不得b的指向了
ps:printf函数仍会读四个字节,但并非原来的四个字节,因为会类型提升,其他三个字节扩充为符号位
#6
无知无畏啊!真是恐怖!
#7
那个位置确实不能用char *代替。举个例子
那a和b的值是一样的么,楼主的2种不同的指针的区别和这里是一样的。
明显,b中,因为char *的存在(char *表示指向的值是一个字节为单位的),导致b只取&str这个地址所指向的数值中的一个字节,而a则是取的4个字节,这就是a和b不同的原因,所以只要将char改为随意一个4字节类型,a和b都是一样的,所以char *改为int *或者long *都是可以的。另外,实验了一下,*(struct *)value和*(int *)value是等效的。
char *str = "abc";
int a = str;
int b = *(char *)(&str);
那a和b的值是一样的么,楼主的2种不同的指针的区别和这里是一样的。
明显,b中,因为char *的存在(char *表示指向的值是一个字节为单位的),导致b只取&str这个地址所指向的数值中的一个字节,而a则是取的4个字节,这就是a和b不同的原因,所以只要将char改为随意一个4字节类型,a和b都是一样的,所以char *改为int *或者long *都是可以的。另外,实验了一下,*(struct *)value和*(int *)value是等效的。
#8
5楼的回答也是正解。
#9
DING
#10
正解!顶!
#11
学了一学期的DOS C就是不行,看不懂...
#12
学下下
#13
看不懂...
#14
我同意你的说法!