动丽后面可以安装货架吗,就是放美团美团外卖箱子的组装图

2007年9月 C/C++大版内专家分月排行榜第三2007年8月 C/C++大版内专家分月排行榜第三2006年11月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。所见所闻(5)
最近在看鸡啄米关于c++的教程,偶然发现了结构体中两个好玩的东西。
首先是结构体成员如果是字符数组,该怎么赋值?
以一个结构体为例:
&&& struct si{
&& &&& &char x[5];
我用的su.x=&abcd&和直接在定义是初始化,均报错。后来经过搜索发现有三种方法:
&&& 第一种是用for循环一个一个元素的赋值;
&&& 第二种是用strcpy(su.x,&abcd&)赋值;
&&& 第三章是用memcpy(su.x,&abcd&,4)赋值。
然后就是激动人心的结构体在内存中的存储方式了。
C语言中结构体的存储方式是采用对齐的方式,目的是提高访问内存的效率。但是,结构体是怎样对齐的呢?
就是变量的存放地址应该能够整除变量的字节数。4字节的变量应该存放在可以被4整除的地址上,8字节同理。
在上述例子中,x存放在0~4上;y存放在5上;z为floa型变量,大小为4字节,所以应该对齐存放在能够被4整除的地址上,为8~11;同理,m为double型变量,大小为8字节,所以应该对齐存放在能够被8整除的地址上,为16~23。综合上面的,该结构体的大小应该为24。
所以,想必大家也就看出来了,struct结构体的存储顺序是会影响存储空间的使用率的。虽然最近经常听到的说法是现在的存储越来越低廉,因此在编码的时候可以不那么在意存储空间的使用率,把更多的精力放在提高程序的运行时间。但是真的是这样吗?我觉得现在随便一个啥数据量都那么大,节约存储空间还是必不可少的。所以在以后定义结构体时,要尽量把相同数据类型的变量连续写才比较好~
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5927次
排名:千里之外
原创:25篇
转载:11篇
(1)(1)(1)(13)(3)(16)(1)今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题。那么就总结一下C语言中结构体赋值的问题吧:
结构体直接赋值的实现
下面是一个实例:
#include &stdio.h&
struct Foo {
}foo1, foo2;
//define two structs with three different fields
void struct_assign(void)
foo2 = foo1;
//structure directly assignment
int main()
foo1.a = 'a';
foo1.b = 1;
foo1.c = 3.14;
struct_assign();
printf("%c %d %lf\n", foo2.a, foo2.b, foo2.c);
我在Ubuntu 13.04下使用gcc 4.7.3 编译运行得到的结果,如下所示:
guohl@guohailin:~/Documents/c$ gcc struct_test1.c -o struct_test1
guohl@guohailin:~/Documents/c$ ./struct_test1
a 1 3.140000
可以从结果上看出,结构体直接赋值在C语言下是可行的,我们看看struct_assign()函数的汇编实现,从而从底层看看C语言是如何实现两个结构体之间的赋值操作的:
struct_assign:
%esp, %ebp
foo1, %eax
%eax, foo2
//copy the first 4 bytes from foo1 to foo2
foo1+4, %eax
%eax, foo2+4
//copy the second 4 bytes from foo1 to foo2
foo1+8, %eax
%eax, foo2+8
//copy the third 4 bytes from foo1 to foo2
foo1+12, %eax
%eax, foo2+12
//copy the forth 4 bytes from foo1 to foo2
这段汇编比较简单,由于结构体的对齐的特性,sizeof(srtruct Foo)=16,通过四次movl操作将foo1的结构体内容拷贝到结构体foo2中。从汇编上看出,结构体赋值,采用的类似于memcpy这种形式,而不是逐个字段的拷贝。
复杂结构体的赋值
如果结构体中含有其它复杂数据类型呢,例如数组、指针、结构体等,从上面的汇编实现可以看出,只要两个结构体类型相同,就可以实现赋值,如下例:
#include &stdio.h&
struct Foo {
double d[2];
char *p_c;
}foo1, foo2;
int main()
char *c = (char *) malloc (4*sizeof(char));
c[0] = 'a'; c[1] = 'b'; c[2] = 'c'; c[3] = '\0';
foo1.n = 1;
foo1.d[0] = 2; foo1.d[1] = 3;
foo1.p_c = c;
foo2 = foo1;
//assign foo1 to foo2
printf("%d %lf %lf %s\n", foo2.n, foo2.d[0], foo2.d[1], foo2.p_c);
运行结果如下:
guohl@guohailin:~/Documents/c$ gcc struct_test2.c -o struct_test2
guohl@guohailin:~/Documents/c$ ./struct_test2
1 2..000000 abc
可以看出结果和我们想象的是一样的。再次验证结构体的赋值,是直接结构体的内存的拷贝!但正是这个问题,如上面的实例,foo1 和 foo2 中p_c 指针都是指向我们申请的一块大小为4个字节的内存区域,这里注意的是,结构体的拷贝只是浅拷贝,即指针p_c的赋值并不会导致再申请一块内存区域,让foo2的p_c指向它。那么,如果释放掉foo1中的p_c指向的内存,此时foo2中p_c变成野指针,这是对foo2的p_c操作就会出现一些不可预见的问题!在C++中引入了一种可以允许用户重载结构体赋值操作运算,那么我们就可以根据语义重载赋值操作。
数组是二等公民
在维基百科上的解释是:
二等公民不是一个正式的术语,用来描述一个社会体系内对一部分人的歧视或对外来人口的政治限制,即使他们作为一个公民或合法居民的地位。 二等公民虽然不一定是奴隶或罪犯,但他们只享有有限的合法权利、公民权利和经济机会,并经常受到虐待或忽视。法律无视二等公民,不向他们提供保护,甚至在制订法律时可能会根本不考虑他们的利益。划分出二等公民的行为,普遍被视为一种侵犯人权的行为。 典型的二等公民所面临的障碍包括但不仅限于(缺乏或丧失表决权):权利被剥夺,限制民事或军事服务(不包括任何情况下的征兵),以及限制,语言,宗教,教育,行动和结社的自由,武器的所有权,婚姻,性别认同和表达,住房和财产所有权 。
从词条上解释可以看出二等公民与一等公民在权利上是有差别的,这个词很有意思作为计算机专业术语,其含义也有异曲同工之妙!同样我们看看维基百科对计算机的术语&"(一等公民)的定义,一般要满足以下几点,
can be stored in variables and data structures
can be passed as a parameter to a subroutine
can be returned as the result of a subroutine
can be constructed at run-time
has intrinsic identity (independent of any given name)
对比着上面的定义来看C语言数组,数组作为一个函数的参数传递时,退化成一个指针; 同时,数组无法作为函数的返回值; 也许让数组更不服气的是,数组之间不能直接赋值操作,如下面的操作就是非法的:
int a[10];
int b[10];
但是如果数组包装在结构体中,那么就能进行赋值了!相比之下,结构体可以作为函数参数和返回值,这就是一等公民的待遇!至于为什么数组必须是二等公民,这是有历史原因的,大家可以参考来看,有时间这块内容我再补上!
参考资料:
International Standard&ISO/IEC 9899
阅读(...) 评论()
一个代码可以创造一个世界,也可以毁灭一个世界!

我要回帖

更多关于 美团的无人货架 的文章

 

随机推荐