100分求问一个c语法问题

mm11214014 2013-05-15 09:38:29
struct CStruct
{
unsigned data[1];
};

int _tmain(int argc, _TCHAR* argv[])
{
CStruct as;
int* a0 = new int;
int* a1 = new int;
int* a2 = new int;
as.data[0] = (unsigned)(a0);
as.data[1] = (unsigned)(a1);
as.data[2] = (unsigned)(a2);

int* b0 = (int*)as.data[0];
int* b1 = (int*)as.data[1];
int* b2 = (int*)as.data[2];
return 0;
}
为什么定义成unsigned以后,可以这样存储并访问数据,麻烦各位解释一下。
...全文
251 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
图灵狗 2013-05-15
  • 打赏
  • 举报
回复
1、编译器并不会帮你检查越界的问题,这个需要程序员自己维护; 2、越界从语法上来讲是正确的,编译器不会报错; 3、越界会非常的危险,因为你在操作并不属于自己的内存,结果难料也难查; 4、你现在没有出问题是因为程序小,恰好没有对其它代码段造成影响,运气好仅此而已。
引用 7 楼 mm11214014 的回复:
[quote=引用 4 楼 turingo 的回复:] 1、unsigned后面不加如何类型的话,默认为unsigned int类型; 2、你的用法可以实现指针的存取,但是注意不要越界; 3、更好的做法是用void*来实现动态类型管理,参考以下代码: typedef void* var_t; int main(int argc, char* argv[]) { var_t vs[10]; int* a0 = new int; int* a1 = new int; int* a2 = new int; vs[0] = (var_t)a0; vs[1] = (var_t)a1; vs[2] = (var_t)a2; int* b0 = (int*)vs[0]; int* b1 = (int*)vs[1]; int* b2 = (int*)vs[2]; return 0; }
很明显下标会越界,你的demo定义的大小是10自然是可以的,但是我现在的疑问是大小定义为1的时候,为何还可以这样使用,另外这个确实是用来实现指针的存取的。[/quote]
kestudio123 2013-05-15
  • 打赏
  • 举报
回复
还是那句话,不提倡故弄玄虚的语法研究,那没有实际意义。代码要规范易懂,能达到使用的目的就行了。
bluewanderer 2013-05-15
  • 打赏
  • 举报
回复
一个很常见的问题,往64位移植的时候怎么办。 然后这么折腾有什么特别的意义?数据没什么特殊情况还是保证原始性比较好,原始意味着没有损失信息的可能。
Carl_CCC 2013-05-15
  • 打赏
  • 举报
回复
引用 2 楼 mm11214014 的回复:
[quote=引用 1 楼 Idle_Cloud 的回复:] 当然可以,只是是危险操作,就比如你定义 char a[10] 你还可以访问a[-1]呢。 这是因为data只是一个地址,首地址,然后他就可以在这个地址上加啊,减啊。但是不受管理的访问可能导致奔溃或意想不到的结果。
这并不是一个危险的操作,工程里有很多这样的代码,如果是unsigned int,这样可能就是危险的操作了,这里的unsigned应该是有其它的用法吧[/quote] 这还不危险啊,而且unsigned 就是 unsigned int.
derekrose 2013-05-15
  • 打赏
  • 举报
回复
可以不可以不是编译器说的算的
lin5161678 2013-05-15
  • 打赏
  • 举报
回复
引用 2 楼 mm11214014 的回复:
这并不是一个危险的操作,工程里有很多这样的代码,如果是unsigned int,这样可能就是危险的操作了,这里的unsigned应该是有其它的用法吧
下标越界 未定义行为 结果不可靠 的确是危险的操作 你所说的 工程里面这样用 有2种可能 1 你水平不行 被你忽略一些重要的细节 2 工程中的代码是错误的
hugett 2013-05-15
  • 打赏
  • 举报
回复
这样当然可行。。地址也不过就是一个数而已。。当然可以用unsigned存储。。不过,这种用法的确。。不那么好。。 另外,unsigned若省略后一个关键字,大多数编译器都会认为是unsigned int。。
mm11214014 2013-05-15
  • 打赏
  • 举报
回复
引用 4 楼 turingo 的回复:
1、unsigned后面不加如何类型的话,默认为unsigned int类型; 2、你的用法可以实现指针的存取,但是注意不要越界; 3、更好的做法是用void*来实现动态类型管理,参考以下代码: typedef void* var_t; int main(int argc, char* argv[]) { var_t vs[10]; int* a0 = new int; int* a1 = new int; int* a2 = new int; vs[0] = (var_t)a0; vs[1] = (var_t)a1; vs[2] = (var_t)a2; int* b0 = (int*)vs[0]; int* b1 = (int*)vs[1]; int* b2 = (int*)vs[2]; return 0; }
很明显下标会越界,你的demo定义的大小是10自然是可以的,但是我现在的疑问是大小定义为1的时候,为何还可以这样使用,另外这个确实是用来实现指针的存取的。
starytx 2013-05-15
  • 打赏
  • 举报
回复
单纯写一个unsigned 默认应该是其他一个东西。话说还是别写这样的代码为好
就是那个党伟 2013-05-15
  • 打赏
  • 举报
回复
特例吧。毕竟一款随性的对程序员权限很大的语言,如果可行,那么不一定合理,不一定合法,但还真就可行了,C的魅力所在吧
图灵狗 2013-05-15
  • 打赏
  • 举报
回复
1、unsigned后面不加如何类型的话,默认为unsigned int类型;
2、你的用法可以实现指针的存取,但是注意不要越界;
3、更好的做法是用void*来实现动态类型管理,参考以下代码:

typedef void* var_t;

int main(int argc, char* argv[])
{
var_t vs[10];
int* a0 = new int;
int* a1 = new int;
int* a2 = new int;

vs[0] = (var_t)a0;
vs[1] = (var_t)a1;
vs[2] = (var_t)a2;

int* b0 = (int*)vs[0];
int* b1 = (int*)vs[1];
int* b2 = (int*)vs[2];

return 0;
}
FancyMouse 2013-05-15
  • 打赏
  • 举报
回复
unsigned作为一个type的时候和unsigned int有啥区别? 工程里有这样的代码,要么是你误解了代码,要么是这工程奇葩。
mm11214014 2013-05-15
  • 打赏
  • 举报
回复
引用 1 楼 Idle_Cloud 的回复:
当然可以,只是是危险操作,就比如你定义 char a[10] 你还可以访问a[-1]呢。 这是因为data只是一个地址,首地址,然后他就可以在这个地址上加啊,减啊。但是不受管理的访问可能导致奔溃或意想不到的结果。
这并不是一个危险的操作,工程里有很多这样的代码,如果是unsigned int,这样可能就是危险的操作了,这里的unsigned应该是有其它的用法吧
Carl_CCC 2013-05-15
  • 打赏
  • 举报
回复
当然可以,只是是危险操作,就比如你定义 char a[10] 你还可以访问a[-1]呢。 这是因为data只是一个地址,首地址,然后他就可以在这个地址上加啊,减啊。但是不受管理的访问可能导致奔溃或意想不到的结果。
mm11214014 2013-05-15
  • 打赏
  • 举报
回复
http://www.douban.com/note/213324857/

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧