struct student test1;
test1.name = "小明" //c++和Java中可以,C语言不行,必须通过strcpy赋值
strcpy(test.name,"小明");
struct datas
{
char *p;
}struct test
{
char p[128];
}int main()
{struct datas d;strcpy(d.p,"哈哈哈");printf("%s\n",d.p);
}
// 编译程序会崩溃,但是把main函数中的datas换成test就可以成功编译
原因是:test中定义的是数组,数组一旦被定义就自动生成空间,而datas中定义的是野指针,野指针必须要malloc。d.p=(char *)malloc(128),即使不初始化它,但至少它有空间了
#include
#include struct student{int score;char *name;
};int main()
{int i;struct student stus[3];struct student max;struct student min;max = min = stus[i];for(i=0;i
接收的是一个地址的时候就不用&,例如stus[i].name那里。
1.如果用结构体指针,就不能用点运算符访问结构体中的变量,要用->
2.结构体指针的偏移问题:偏移整个结构体的大小
struct student {int score;char name[128]; }
指针偏移一次,移动4+128=132个字节
#include
#include struct student
{int score;char *name;
};struct student *init(int len)
{int i;struct student *p =(struct student *)malloc(len*sizeof(struct student));//开辟len长度的空间来存放名字和分数for(i=0;iname = (char *)malloc(128);//指针所指向的地址需要存放数据的时候需要申请空间。scanf("%s",p->name);printf("请输入第%d个学生的分数:\n",i+1);scanf("%d",&(p->score));p++; }return p-len; //容易落下,不返回或只返回p都影响下一个函数的执行,//因为在该函数执行完后,指针已到了末尾,需要调回数组头的位置
}
void print(struct student *p,int len)
{int i;for(i=0;iname,p->score);p++;}
}struct student *max(struct student *p,int len)
{ //先遍历struct student *max = p; int i;for(i=0;iscore < p->score){max = p; } p++;} printf("max %s:%d\n",max->name,max->score);return max;
}struct student *min(struct student *p,int len)
{struct student *min = p; int i;for(i=0;iscore > p->score){min = p; } p++;} printf("min %s:%d\n",min->name,min->score);return min;}float average(struct student *p,int len)
{int i;int total = 0;for(i=0;iscore;p++;}printf("average:%f\n",(float)total/len);return (float)total/len;
}
int main()
{int len=0;int i;printf("人数:\n");scanf("%d",&len);struct student *ps = init(len); //定义个指针指向初始化函数,获取数组,len决定数组长度print(ps,len);max(ps,len);min(ps,len);average(ps,len);system("pause");return 0;
}
两条原则:
1.结构体成员的偏移量必须是成员大小的整数倍
2.结构体大小必须是所有成员大小的整数倍(数组和结构体除外)
这种对齐方式很浪费空间,但是提高了计算机的访问效率
struct s1
{char b; //1 {} int c; //4 {} {}{}{} {}{}{}{} char a; //1 {} {}{}{} {}{}{}{} {} int d; //4 {} {}{}{} {}{}{}{} {} {}{}{} {}{}{}{}char k; //1 {} {}{}{} {}{}{}{} {} {}{}{} {}{}{}{} {}
}
实际的大小是20
b大小是1,不偏移,没有偏移值(因为他是头),此时字节数是1。
c大小是4,偏移值(原则1)为1+3=4(+3是对齐用的),加上它的大小4,此时字节数为1+3+4=8
a大小是1,大小是1,不需要对其,直接加,此时字节数为1+3+4+1 = 9
d大小是4,偏移值为1+3=4(+3是对齐用的),加上它的大小4,此时字节数为1+3+4+1 +3 +4 = 16
k大小是1,不需要对其,直接加,此时字节数为1+3+4+1 +3 +4 +1= 17
但是根据原则2,还需要补齐到20(int和char的整数倍)
struct test
{char a;int b;struct test1{char aa;int bb;}float c;
}
这种情况,计算test结构体的大小=1+3+4+4=12,不计算test1的大小,因为test1只是一个声明,不占空间,但如果test1是下面这种情况,就计算它的大小:
struct test1
{char aa;int bb;
}stu; (除了声明test1结构体还声明了stu这个变量)
对结构体对齐的方式进行限制
#pragma pack(4):限制跟4个字节对齐,如果结构体中最大的成员有超过4个字节的,就按4个字节对其;如果没超过,就按最大的成员大小算
上一篇:帮我写一首总理爱十年难忘的情诗
下一篇:关于报表打印