华硕笔记本i5系列i5-5200u 920m显卡,8G内存可以完吃鸡吗?

C#中结构体声明数组成员怎么初始化 - C#&&&&>>&& C#中结构体声明数组成员如何初始化?我声明了以下的结构体: &
struct indiv &
public int[] &
bestindiv=new indiv(); &
worstindiv= new indiv(); &
currentbest = new indiv(); &
indivi[] pop = new indiv[500];vs2010警告说 & 从未对字段“Bishop.gafor.indivl.chrom”赋值,字段将一直保持其默认值 null C:\Documents and Settings\Administrator\桌面\DSREA-MC2.3\Bishop\gafor.cs编译可以通过,但是运行的时候出错了。请教各位大侠,如何解决这个问题?------解决方案--------------------哪来的chrom,你出错在哪出的错,你这几行应该不会出错另外
indivi[]写错了,应该是 indiv[]
------解决方案--------------------你遇到的错误和你贴的代码无关
------解决方案--------------------找这个文件gafor.cs里有错误
------解决方案--------------------
一般用静态构造函数, struct indiv
private static indiv s_
static indiv()
s_default.chr=
s_default.fit=0.0;
public static indiv Default
public int[]
indiv bestindiv=indiv.D//这样就可以初始化成员, &
------解决方案--------------------500个元素的结构体数组,就比较麻烦,最好把初始化chr数组作为一个方法,struct indiv{...
public void initialize(int nArrayLength)
chr=new int[nArrayLength];
//如果要初始化:
for(int i=0;i&nArrayLi++)
chr[i]=...;
} private static indiv s_
static indiv()
s_default.chr=
s_default.fit=0.0;
public static indiv Default
}}indivi[] pop = new indiv[500];for(int i=0;i&500;i++){
indivi[i]=indivi.D
indivi[i].initialize(50);}博客访问: 33335
博文数量: 22
博客积分: 345
博客等级: 一等列兵
技术积分: 175
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
指向结构体类型数组的指针的使用定义一个结构体类型数组,其数组名是数组的首地址,这一点前面的课程介绍得很清楚。定义结构体类型的指针,既可以指向数组的元素,也可以指向数组,在使用时要加以区分。[例7-3] 在例7 - 2中定义了结构体类型,根据此类型再定义结构体数组及指向结构体类型的指针。struct data {intday,month,};struct stu/*定义结构体*/{char name[20];/嵌*套的结构体类型成员*/};struct stustudent[4],*p;定/*义结构体数组及指向结构体类型的指针*/作p=student,此时指针p就指向了结构体数组student。p是指向一维结构体数组的指针,对数组元素的引用可采用三种方法。1)地址法student+i和p+i均表示数组第i个元素的地址,数组元素各成员的引用形式为:(student+i)->name、(student+i)->num和(p+i)->name、(p+i)->num等。student+i和p+i与&student[i]意义相同。2)指针法若p指向数组的某一个元素,则p++就指向其后续元素。3)指针的数组表示法若p=student,我们说指针p指向数组student,p[i]表示数组的第i个元素,其效果与student[i]等同。对数组成员的引用描述为:p[i].name、p[i].num等。
阅读(11229) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。5803人阅读
C 系列(18)
C语言结构体里的成员数组和指针(关于零数组)
【转自酷壳网:/articles/11377.html &作者:陈皓】
单看这文章的标题,你可能会觉得好像没什么意思。你先别下这个结论,相信这篇文章会对你理解C语言有帮助。这篇文章产生的背景是在微博上,看到同学出了一个关于C语言的题,。微博截图如下。我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章。
为了方便你把代码copy过去编译和调试,我把代码列在下面:
#include &stdio.h&
struct str{
char s[0];
struct foo {
struct str *a;
int main(int argc, char** argv) {
struct foo f={0};
if (f.a-&s) {
printf( f.a-&s);
你编译一下上面的代码,在VC++和GCC下都会在14行的printf处crash掉你的程序。说这个是个经典的坑,我觉得这怎么会是经典的坑呢?上面这代码,你一定会问,为什么if语句判断的不是f.a?而是f.a里面的数组?我个人觉得这主要还是对C语言理解不深,如果这算坑的话,那么全都是坑。
接下来,你调试一下,或是你把14行的printf语句改成:
printf(&%x\n&,f.a-&s);
你会看到程序不crash了。程序输出:4。 这下你知道了,访问0×4的内存地址,不crash才怪。于是,你一定会有如下的问题:
1)为什么不是 13行if语句出错?f.a被初始化为空了嘛,用空指针访问成员变量为什么不crash?
2)为什么会访问到了0×4的地址?靠,4是怎么出来的?
3)代码中的第4行,char s[0] 是个什么东西?零长度的数组?为什么要这样玩?
让我们从基础开始一点一点地来解释C语言中这些诡异的问题。
·结构体中的成员
首先,我们需要知道——所谓变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字的,只知道地址。
所以有了——栈内存区,堆内存区,静态内存区,常量内存区,我们代码中的所有变量都会被编译器预先放到这些内存区中。
有了上面这个基础,我们来看一下结构体中的成员的地址是什么?我们先简单化一下代码:
struct test{
&&& char *p;
上面代码中,test结构中i和p指针,在C的编译器中保存的是相对地址——也就是说,他们的地址是相对于struct test的实例的。
如果我们有这样的代码:
我们用gdb跟进去,对于实例t,我们可以看到:
# t实例中的p就是一个野指针
$1 = {i = 0, c = 0'\000', d = 0 '\000', p = 0x\355I\211\...&}
# 输出t的地址
(gdb) p &t
$2 = (struct test *)0x7fffffffe5f0
#输出(t.i)的地址
(gdb) p &(t.i)
$3 = (char **)0x7fffffffe5f0
#输出(t.p)的地址
(gdb) p &(t.p)
$4 = (char **)0x7fffffffe5f4
我们可以看到,t.i的地址和t的地址是一样的,t.p的址址相对于t的地址多了个4。说白了,t.i 其实就是(&t +0×0),&t.p 的其实就是 (&t +0×4)。0×0和0×4这个偏移地址就是成员i和p在编译时就被编译器给hard code了的地址。于是,你就知道,不管结构体的实例是什么——访问其成员其实就是加成员的偏移量。
下面我们来做个实验:
struct test{
int main(){
struct test *pt=NULL;
编译后,我们用gdb调试一下,当初始化pt后,我们看看如下的调试:(我们可以看到就算是pt为NULL,访问其中的成员时,其实就是在访问相对于pt的内址)
(gdb) p pt
$1 = (struct test *)0x0
(gdb) p pt-&i
Cannot access memoryat address 0x0
(gdb) p pt-&c
Cannot access memoryat address 0x4
(gdb) p pt-&p
Cannot access memoryat address 0x8
注意:上面的pt-&p的偏移之所以是0×8而不是0×6,是因为内存对齐了(我在64位系统上)。
好了,现在你知道为什么原题中会访问到了0×4的地址了吧,因为是相对地址。
相对地址有很好多处,其可以玩出一些有意思的编程技巧,比如把C搞出面向对象式的感觉来。
·指针和数组的差别
有了上面的基础后,你把源代码中的structstr结构体中的chars[0];改成char*s;试试看,你会发现,在13行if条件的时候,程序因为Cannot accessmemory就直接挂掉了。为什么声明成char s[0],程序会在14行挂掉,而声明成char *s,程序会在13行挂掉呢?那么char*s 和char s[0]有什么差别呢?
在说明这个事之前,有必要看一下汇编代码,用GDB查看后发现:
·&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&对于char s[0]来说,汇编代码用了lea指令,lea 0×04(%rax), %rdx
·&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&对于char*s来说,汇编代码用了mov指令,mov 0×04(%rax), %rdx
lea全称load effective address,是把地址放进去,而mov则是把地址里的内容放进去。所以,就crash了。
从这里,我们可以看到,访问成员数组名其实得到的是数组的相对地址,而访问成员指针其实是相对地址里的内容(这和访问其它非指针或数组的变量是一样的)
换句话说,对于数组char s[10]来说,数组名 s 和 &s 都是一样的(不信你可以自己写个程序试试)。在我们这个例子中,也就是说,都表示了偏移后的地址。这样,如果我们访问 指针的地址(或是成员变量的地址),那么也就不会让程序挂掉了。
正如下面的代码,可以运行一点也不会crash掉(你汇编一下你会看到用的都是lea指令):
struct test{
char s[10];
int main(){
struct test *pt=NULL;
printf(&&s = %x\n&,pt-&s); //等价于printf(&%x\n&, &(pt-&s) );
printf(&&i = %x\n&,&pt-&i); //因为操作符优先级,我没有写成&(pt-&i)
printf(&&c = %x\n&,&pt-&c);
printf(&&p = %x\n&,&pt-&p);
·关于零长度的数组
首先,我们要知道,0长度的数组在ISO C和C++的规格说明书中是不允许的。这也就是为什么在VC++2012下编译你会得到一个警告:“arning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组”。
那么为什么gcc可以通过而连一个警告都没有?那是因为gcc为了预先支持C99的这种玩法,所以,让“零长度数组”这种玩法合法了。关于GCC对于这个事的文档在这里:“”,文档中给了一个例子(我改了一下,改成可以运行的了):
#include&stdlib.h&
#include&string.h&
struct line {
char contents[0]; // C99的玩法是:char contents[]; 没有指定数组长度
int main(){
int this_length=10;
struct line *thisline = (struct line *)
malloc (sizeof (structline) + this_length);
thisline-&length = this_
memset(thisline-&contents, 'a',this_length);
上面这段代码的意思是:我想分配一个不定长的数组,于是我有一个结构体,其中有两个成员,一个是length,代表数组的长度,一个是contents,代码数组的内容。后面代码里的 this_length(长度是10)代表是我想分配的数据的长度。(这看上去是不是像一个C++的类?)这种玩法英文叫:Flexible Array,中文翻译叫:柔性数组。
我们来用gdb看一下:
(gdb) p thisline
$1 = (struct line *)0x601010
(gdb) p *thisline
$2 = {length = 10,contents = 0x601010 &\n&}
(gdb) pthisline-&contents
$3 = 0x601014&aaaaaaaaaa&
我们可以看到:在输出*thisline时,我们发现其中的成员变量contents的地址居然和thisline是一样的(偏移量为0×0??!!)。但是当我们输出thisline-&contents的时候,你又发现contents的地址是被offset了0×4了的,内容也变成了10个‘a’。(我觉得这是一个GDB的bug,VC++就能很好的显示)
我们继续,如果你sizeof(char[0])或是 sizeof(int[0]) 之类的零长度数组,你会发现sizeof返回了0,这就是说,零长度的数组是存在于结构体内的,但是不占结构体的size。你可以简单的理解为一个没有内容的占位标识,直到我们给结构体分配了内存,这个占位标识才变成了一个有长度的数组。
看到这里,你会说,为什么要这样搞啊,把contents声明成一个指针,然后为它再分配一下内存不行么?就像下面一样。
struct line {
int main(){
int this_length=10;
struct line *thisline = (struct line*)malloc (sizeof (struct line));
thisline-&contents = (char*) malloc(sizeof(char) * this_length );
thisline-&length = this_
memset(thisline-&contents, 'a',this_length);
这不一样清楚吗?而且也没什么怪异难懂的东西。是的,这也是普遍的编程方式,代码是很清晰,也让人很容易理解。即然这样,那为什么要搞一个零长度的数组?有毛意义?!
这个事情出来的原因是——我们想给一个结构体内的数据分配一个连续的内存!这样做的意义有两个好处:
第一个意义是,方便内存释放。如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。(读到这里,你一定子就觉得C++的虚函数会让这事容易和干净很多)
第二个原因是,这样有利于访问速度。连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)
我们来看看是怎么个连续的,用gdb的x命令来查看:(我们知道,用struct line {}中的那个char contents[]不占用结构体的内存,所以,struct line就只有一个int成员,4个字节,而我们还要为contents[]分配10个字节长度,所以,一共是14个字节)
(gdb) x /14b thisline
0x601010:&&&&&& 10&&&&&0&&&&&& 0&&&&&& 0&&&&&&97&&&&& 97&&&&& 97&&&&&97
0x601018:&&&&&& 97&&&&&97&&&&& 97&&&&& 97&&&&&97&&&&& 97
从上面的内存布局我们可以看到,前4个字节是 int length,后10个字节就是char contents[]。
如果用指针的话,会变成这个样子:
(gdb) x /16b thisline
0x601010:&&&&&& 1&&&&&&0&&&&&& 0&&&&&& 0&&&&&&0&&&&&& 0&&&&&& 0&&&&&&0
0x601018:&&&&&& 32&&&&&16&&&&& 96&&&&& 0&&&&&&0&&&&&& 0&&&&&& 0&&&&&&0
(gdb) x /10bthis-&contents
0x601020:&&&&&& 97&&&&&97&&&&& 97&&&&& 97&&&&&97&&&&& 97&&&&& 97&&&&&97
0x601028:&&&&&& 97&&&&&97
上面一共输出了四行内存,其中,
·&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第一行前四个字节是 int length,第一行的后四个字节是对齐。
·&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第二行是char* contents,64位系统指针8个长度,他的值是0×20 0×10 0×60 也就是0×601020。
·&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&第三行和第四行是char* contents指向的内容。
从这里,我们看到,其中的差别——数组的原地就是内容,而指针的那里保存的是内容的地址。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:351026次
积分:3643
积分:3643
排名:第7176名
原创:68篇
评论:144条
阅读:54784
文章:13篇
阅读:31886
文章:15篇
阅读:12337513:24 提问
结构体数组中有数组成员,怎么对结构体数组查询并追加,追加至上限,删除最老记录
int dataNumber=0;
struct Target{
int targetNo;
// Id of Target, 0: Sun
double xpos, ypos, ut1_
double appra[49],appdec[49],gast[49],t[49];
}target[100];
int calcSun(int year, int month, int day, double hour, struct Target *t)
t-&timestamp=time(&timep);
printf("timestamp=%d\n",timep);
Make structures of type 'on_surface' and 'observer-on-surface' containing
the observer's position and weather (latitude, longitude, height,
temperature, and atmospheric pressure).
make_on_surface (latitude,longitude,height,temperature,pressure, &geo_loc);
make_observer_on_surface (latitude,longitude,height,temperature,pressure,
&obs_loc);
Make structures of type 'object' for the Mercury....Sun,Moon.
make_cat_entry ("DUMMY","xxx",0,0.0,0.0,0.0,0.0,0.0,0.0,&dummy_star);
if ((error = make_object (0,10,"sun",&dummy_star, &sun)) != 0)
printf ("Error %d from make_object (sun)\n", error);
return (error);
get_leap_sec(MJD,0.,&leapsecondt);
//printf("Leap: %lf\n",leapsecondt);
if (!get_iers_data(MJD, &ut1_utc, &xx, &yy))
printf("Error retrieve IERS Data\n");
t-&ut1_utc = ut1_
for(i=0;i&49;i++)
jd_utc = julian_date (year,month,day,hour);
jd_tt = jd_utc+((double) leapsecondt + 32.184) / 86400.0;
jd_ut1 = jd_utc + ut1_utc / 86400.0;
delta_t = 32.184 + leapsecondt - ut1_
Apparent and topocentric place of the SUN.
if ((error = app_planet (jd_tt,&sun,accuracy, &ra,&dec,&dis)) != 0)
printf ("Error %d from app_planet.", error);
return (error);
/* if ((error = topo_planet (jd_tt,&sun,delta_t,&geo_loc,accuracy,
&rat,&dect,&dist)) != 0)
printf ("Error %d from topo_planet.", error);
return (error);
Greenwich and local apparent sidereal time and Earth Rotation Angle.
if ((error = sidereal_time (jd_ut1,0.0,delta_t,0,1,accuracy, &gast)) != 0)
printf ("Error %d from sidereal_time.", error);
return (error);
t-&appra[i]=
t-&appdec[i]=
t-&gast[i]=
//printf("appra[%d]=%.15f appdec[%d]=%.15f gast[%d] =%.15f t[%d]=%.15f\n",i,t-&appra[i],i,t-&appdec[i],i,t-&gast[i],i,t-&t[i]);
hour=hour+0.5;
// Query OK.
fp=fopen("ephpos.dat","r+");
char buffer[1024];
if(fp==NULL)
printf("file open failed !\n");
while(fgets(buffer,sizeof(buffer),fp) ) {
dataNumber++;
//printf("buffer=%s\n",buffer);
fseek(fp,0,0);
printf("dataNumber=%d\n",dataNumber);
for(i=0;i&dataNi++)
fscanf(fp,"%d %d %lf %lf %lf %lf %lf %lf %lf %lf\n",&target[i].targetNo,&target[i].Mjd,&target[i].xpos,&target[i].ypos,
&target[i].ut1_utc,&target[i].appra[i],&target[i].appdec[i],&target[i].gast[i],&target[i].t[i]);
printf("%d %d %.15f %.15f %.15f %.15f %.15f %.15f %.15f %.15f\n",target[i].targetNo,target[i].Mjd,target[i].xpos,target[i].ypos,
target[i].ut1_utc,target[i].appra[i],target[i].appdec[i],target[i].gast[i],target[i].t[i]);
//getchar();
if (target[i].targetNo == obsTarget &&target[i].jd ==JD)
printf("Query ok!\n");
sprintf(result,"%d %.15f %.15f %.15f %.15f %.15f %.15f %.15f %.15f\n",target[i].Mjd,target[i].jd,target[i].xpos,target[i].ypos,
target[i].ut1_utc,target[i].appra[i],target[i].appdec[i],target[i].gast[i],target[i].t[i]);
printf("Result:%s\n",result);
// Query failed,compute from calcsun.
if(i==dataNumber)
printf("Query failed!\n");
//printf("i=%d dataNumber=%d\n",i,dataNumber);
calcSun(year, month, day, tt,&target[dataNumber++]);
printf("Insert a new record!\n");
fprintf(fp,"%d %d %.15f %.15f %.15f %.15f %.15f %.15f %.15f %.15f\n",obsTarget,MJD,JD,target[i].xpos,target[i].ypos,
target[i].ut1_utc,target[i].appra[i],target[i].appdec[i],target[i].gast[i],tt);
printf("%d %d %.15f %.15f %.15f %.15f %.15f %.15f %.15f %.15f\n",obsTarget,MJD,JD,target[i].xpos,target[i].ypos,
target[i].ut1_utc,target[i].appra[i],target[i].appdec[i],target[i].gast[i],tt);
//sprintf(result,"target[%d]=%d target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f target[%d]=%.15f\n",i,MJD,
//i,JD,i,target[i].xpos,i,target[i].ypos,i,target[i].ut1_utc,i,target[i].appra[i],i,target[i].appdec[i],i,target[i].gast[i],i,target[i].t[i]);
// printf("Result:%s\n",result);
//RA=parabola(target[i].appra,target[i].t,49,tt);
// DEC=parabola(target[i].appdec,target[i].t,49,tt);
// GAST=parabola(target[i].gast,target[i].t,49,tt);
//sprintf(result,"%d %.15f %.15f %.15f %.15f %.15f %.15f %.15f\n",MJD,JD,target[i].xpos,target[i].ypos,target[i].ut1_utc,
// RA,DEC,GAST);
//printf("Result:%s\n",result);
// select the long timestamp to update data
if(dataNumber&100)
printf("trying delete the long timestamp data in the target array...\n");
time_t m=target[1].
for(i=1;i&101;i++)
if(target[i].timestamp&=m);
m=target[i].
target[i]=target[dataNumber++];
fclose(fp);
其他相似问题

我要回帖

更多关于 华硕飞行堡垒i56300 的文章

 

随机推荐