码迷,mamicode.com
首页 > 其他好文 > 详细

理解结构体

时间:2015-12-20 17:44:37      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:c语言   结构体   

结构基础知识

在C语言中结构体是一种数据结构。结构体可被声明为变量,指针或者数组等;同时,也是一些元素的集合,这些元素被称为结构体成员,且这些成员可以是不同的类型,成员一般用名字访问

struct Stu   //Stu为结构体标签
{
    char name[20];
    int age;
    charsex[5];
    char tele[12];
    char addr[30];//成员
}stu1,stu2;
//stu1和stu2均为全局的结构体变量,
int main()
{
   struct Stu stu;//创建结构体变量
}

匿名结构体,将结构体标签省略,则必须在后面申明全局变量,但是也存在类型不同的问题

struct
{
    char name[20];
    int age;
    charsex[5];
    char tele[12];
    char addr[30];//成员
}stu1;
struct
{
    char name[20];
    int age;
    charsex[5];
    char tele[12];
    char addr[30];//成员
}*pstu;
//两结构体成员一模一样
int main()
{
pstu=&stu1;/*error,两个类型不同,因为是匿名的结构体类型,通过其创建的变量编译器会认为他们是不同的类型*/
}

typedef简化struct

struct Stu 
{
    char name[20];
    int age;
    charsex[5];
    char tele[12];
    char addr[30];//成员
}stu1,arrstu[10],*pstu;

typedef  struct Stu stu;/*如果typedef加在结构体前面,则后面的全局变量则表示为这个结构体的新名字*/

int main()
{
    stu stu2;//省略struct
    stu arr2[10];
    stu *pstu;
    
    return 0;
}

结构体成员

1.直接访问

struct stu 
{
    char name[20];
    int age;
    char sex[5];
    char tele[12];
    char addr[30];//成员
};

typedef struct stu stu;

int main()
{
stu stu;//结构体变量
//stu.name="bit";//error,不能给常量赋值
strcpy(stu.name,"aaa");
stu.age=10;
printf("name=%s",stu.name);
printf("age=%d",stu.age);
return 0;
}

2.间接访问

-> 用于结构体指针

.  用于结构体变量

struct stu 
{
    char name[20];
    int age;
    char sex[5];
    char tele[12];
    char addr[30];//成员
};

typedef struct stu* pstu;

int main()
{
stu stu;//结构体变量
pstu pstu1=&stu;
//strcpy((*pstu1).name,"aaa");
//(*pstu1).age=20;
strcpy(pstu1->name,"aaa");
return 0;
}

结构体自引

例1.错误的方式

struct A
{
char name[10];
int age;
struct A sa;
}
int main()
{
struct A sa;
}

用递归造成死循环,不断的自己引用自己

改正

struct A
{
char name[10];
int age;
struct A *sa;//大小为一个确切的值,通过指针找到下一个
}
int main()
{
struct A sa1;
struct A sa2;
struct A sa3;
sa1.pa=&sa2;
sa2.pa=&sa3;
sa3.pa=NULL;
}

若想用typedef改写,则

typedef struct A//结构体内部嵌套同类型指针,重命名不能是匿名的结构体
{
char name[10];
int age;
struct A *sa;
}a;
int main()
{
    a sa1;
    a sa2;
    a sa3;
sa1.pa=&sa2;
sa2.pa=&sa3;
sa3.pa=NULL;
}

不完整声明

struct A
{
int i;
struct B b;
};
struct B
{
int i;
struct A a;
};
//不允许这种写法,会一直相互调用下去

改写为

struct B;
struct A
{
int i;
struct B *b;
};
struct B
{
int i;
struct A *a;
};


结构体初始化

struct stu
{
char name[10];
int age;
char sex[4];
char tel[12];
char add[20];
};
int main()
{
struct stu stu={"aaa",12,"male","123","xia"};
printf("%s\n",stu.name);
printf("%d\n",stu.age);

return 0;
}

结构体中含有结构体的初始化

struct A
{
 int a;
 char c;
 double d;
};
struct stu
{
char name[10];
int age;
char sex[4];
char tel[12];
char add[20];
struct A sa;
};
int main()
{
struct stu stu={"aaa",12,"male","123","xian"};//不完全初始化
struct stu stu={"aaa",12,"male","123","xian",{1,‘w‘,12.34}};//sa前的成员不可省略
printf("%s\n",stu.name);
printf("%d\n",stu.age);
printf("%1f\n",stu.sa.d);

return 0;
}

结构体大小

struct s
{
int a;
char c;
couble d;
};
struct s2
{
int a;
double d;
char c;
};
int main()
{
printf("%d\n",sizeof(struct s));
printf("%d\n",sizeof(struct s2));
return 0;
}
//输出16
      24

存在内存对齐规则

  1. 第一个成员在与结构体变量偏移地址为0的地址处

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址

   对齐数=编译器默认的一个对齐数与该成员大小的较小值

   vs中默认8,linux默认4

3.  结构体总大小为最大对齐数(每个成员变量除了第一个成员都有个对齐数)的整数倍

4.  如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍出,结构体的整体大小就是所有最大对其数(含嵌套结构体的对齐数)的整数倍

struct A
{
double d;
char c;  
short s;  
dpuble d2;
};
int main()
{
printf("%d",sizeof(struct A));//24
printf("%d",offsetof(struct A,d));//0
}

offsetof是求每个类型对其的地址

本文出自 “无以伦比的暖阳” 博客,请务必保留此出处http://10797127.blog.51cto.com/10787127/1726525

理解结构体

标签:c语言   结构体   

原文地址:http://10797127.blog.51cto.com/10787127/1726525

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!