C语言共同体占字节数,9.C语言(复合类型--结构体-共同体)

结构体

1.结构体定义和初始化

#define _CRT_SECURE_NO_WARNINGS

#include #include //定义一个结构体【类型】

//strut 是关键字

//struct Worker合起来才是结构体类型

//结构体内部定义的变量不能直接赋值

//结构体只是一个类型,没有定义变量前,

//是没有分配空间的,不能赋值(C与C++不同,C++可以在定义的时候赋值)

struct Worker {

int age;

char name[5];

int score;

};//必须有分号

int main() {

//定义结构体【变量】

//类型名 变量名

struct Worker wo;

//第一种初始化方式,和数组一样,使用大括号

struct Worker wo2 = {20,"hahah",100};

//第二种初始化方式

struct Worker wo3;

wo3.age = 21;

//name是数组名,数组名是常量,不能直接赋值修改使用strcpy

//wo3.name = "zhangsan";

strcpy(wo3.name, "zhangsan");

wo3.score = 99;

//第三种初始化方式,通过指针,使用->

struct Worker *p;

p = &wo3;

p->age = 22;

p->score = 90;

strcpy(p->name, "lisi");

//任何结构体变量都可以用.或->操作成员

//wo3取地址就是一个指针

(&wo3)->age = 11;

//p加上一个*就是它指向的内存,也就是wo3

(*p).age = 12;

system("pause");

}

2.定义结构体变量的方式

1.先声明结构体类型,再定义变量名

struct Worker {

int age;

char name[5];

int score;

};

struct Worker wo;

2.在声明类型的同时定义变量

struct Worker {

int age;

char name[5];

int score;

}wo,wo2;

3.直接定义结构体类型变量(匿名,无类型名),这种方式定义的结构体,无法在外部定义其他的结构体变量,只能使用已经定义好的

struct {

int age;

char name[5];

int score;

}wo,wo2;

3.结构体数组的定义和赋值

第一种初始化方式

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Worker {

int age;

char name[10];

int score;

};

int main() {

struct Worker wo;

//定义一个结构体数组

struct Worker a[5];

//给第一个结构体元素赋值

a[0].age = 18;

strcpy(a[0].name, "ren");

a[0].score = 50;

//给第二个结构体元素赋值

(a + 1)->age = 10;

strcpy((a + 1)->name, "zhen");

(a + 1)->score = 30;

//给第三个结构体元素赋值

(*(a + 2)).age = 20;

strcpy((*(a + 2)).name, "ming");

(*(a + 2)).score = 9;

//定义一个指针指向这个结构体数组

struct Worker *p = a;

//给第四个结构体元素赋值

p[3].age = 21;

strcpy(p[3].name, "ying");

p[3].score = 100;

//给第五个结构体元素赋值

(p + 4)->age = 32;

strcpy((p + 4)->name, "zi");

(p + 4)->score = 10;

int i = 0;

int n = sizeof(a) / sizeof(a[0]);

for (i = 0; i < n; i++) {

printf("%d,%s,%d\n", p[i].age, p[i].name, p[i].score);

}

system("pause");

}

第二种初始化方式,下边a a1 a2都是初始化一个结构体数组

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Worker {

int age;

char name[10];

int score;

};

int main() {

struct Worker a2[5] =

{

{11,"a",12},

{12,"b",13},

{13,"c",14},

{14,"d",15},

{15,"e",16}

};

struct Worker a3[5] = {

11,"a",12 ,

12,"b",13,

13,"c",14,

14,"d",15,

15,"e",16

};

struct Worker a[5] = {

11,"a",12 ,12,"b",13,13,"c",14,14,"d",15,15,"e",16

};

int i = 0;

int n = sizeof(a) / sizeof(a[0]);

for (i = 0; i < n; i++) {

printf("%d,%s,%d\n", a[i].age,a[i].name, a[i].score);

}

system("pause");

}

4.结构体嵌套

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

struct Worker {

int age;

struct Manager m;

};

int main() {

//定义一个结构体Worker变量

struct Worker w;

//通过结构体变量给这个结构体赋值

w.age = 20;

w.m.salary = 20000;

printf("%d,%d\n", w.age,w.m.salary);

//定义一个结构体指针指向这个结构体,通过指针赋值

struct Worker *p = &w;

p->age = 21;

p->m.salary = 30000;

p->m.year = 2018;

printf("%d,%d,%d\n", w.age, w.m.salary,w.m.year);

//直接在定义的时候初始化赋值,这种赋值形式可读性很差

struct Worker woker = {22,19999,2019};

printf("%d,%d,%d\n", woker.age, woker.m.salary,woker.m.year);

system("pause");

}

5.相同类型的结构体变量可以相互赋值

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

int main() {

//相同类型的变量可以通过=号赋值

int a = 10;

int b;

b = a;

printf("%d\n",b);

//相同类型的结构体变量也可以相互赋值

struct Manager s1 = {20000,2018};

struct Manager s2;

s2 = s1;

printf("%d,%d\n",s2.salary,s2.year);

system("pause");

}

6.结构体的值传递

结构体值传递和普通数据类型的值传递原理是相同的,把结构体变量m2传递到setManager方法中,相当于把m2的值赋给了形参m(相同类型的结构体变量可以赋值),此时m和m2内存中存储的值是相同的,但是二者没有直接联系,然后在方法setManager中给m中的元素重新赋值,打印结果如下,可以看出,方法执行完成后销毁,原来的m2的内存空间并不受影响

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

void setManager(struct Manager m) {

m.salary = 1000;

m.year = 2018;

printf("setManager %d %d\n", m.salary, m.year);

}

int main() {

struct Manager m2 = {10000,2019};

setManager(m2);

printf("setManager %d %d\n", m2.salary, m2.year);

system("pause");

}

打印

setManager 1000 2018

setManager 10000 2019

请按任意键继续. . .

7.结构体的地址传递

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

void setManager(struct Manager *m) {

m->salary = 1000;

m->year = 2018;

printf("setManager %d %d\n", m->salary, m->year);

}

int main() {

struct Manager m2 = {10000,2019};

setManager(&m2);

printf("setManager %d %d\n", m2.salary, m2.year);

system("pause");

}

打印

setManager 1000 2018

setManager 1000 2018

请按任意键继续. . .

8.结构体指针指向栈区空间

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

int main() {

//在栈内存定义一个结构体变量

struct Manager m;

//定义一个结构体指针指向结构体变量m

struct Manager *p;

p = &m;

p->salary = 1999;

p->year = 2018;

printf("%d %d\n", m.salary, m.year);

system("pause");

}

9.结构体指针指向堆区空间

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

};

int main() {

struct Manager *p;

//在堆内存开辟一块空间并由p指向它

p = (struct Manager*)malloc(sizeof(struct Manager));

if (p == NULL) {

printf("malloc err\n");

return 0;

}

p->salary = 1999;

p->year = 2018;

printf("%d %d\n", p->salary, p->year);

if (p != NULL) {

free(p);

p = NULL;

}

system("pause");

}

10.结构体中的指针变量

#define _CRT_SECURE_NO_WARNINGS

#include #include struct Manager {

int salary;

int year;

char *name;

};

int main() {

struct Manager m;

//在堆区开辟空间并由结构体中的成员变量指向它

//这里是在堆区开辟空间由它指向这个空间,当然也

//可以在栈中定义一个变量由这个指针指向他

m.name =(char *) malloc(strlen("renzhenming") + 1);

strcpy(m.name, "renzhenming");

m.salary = 10000;

m.year = 2019;

printf("%d %d %s\n", m.salary, m.year,m.name);

if (m.name != NULL) {

free(m.name);

m.name = NULL;

}

system("pause");

}

共同体(共用体 联合体)

由于共同体中所有成员公用同一份内存,所以共同体中不可以同时操作两个或两个以上得元素,因为当你操作其中一个,加入给其中一个附了值,那么另一个值就会发生变化,因为内存已经改变了,如下程序中,共同体所占内存为4个字节,因为int最大,int占4个字节,给c赋值0x44332211后,刚好占满内存,由于abc所指向得首地址是相同得,所以a指向从首地址开始第一个字节,那么打印就是11,b指向从首地址开始前两个字节,那么打印就是2211,c指向从首地址开始到结尾这块内存,打印就是44332211

476d352e50125a173e1c0305005855c0.png

共同体内存分布.png

#define _CRT_SECURE_NO_WARNINGS

#include #include union Manager {

unsigned char a;

unsigned short b;

unsigned int c;

};

int main() {

//结构体大小可以简单得认为是成员大小得累加

//共同体得大小为最大成员得大小,成员中最大得是int,所以打印为4

printf("%lu\n", sizeof(union Manager));

//共同体共有一块内存,所有成员地址都一样

union Manager m;

printf("%p,%p,%p,%p\n", &m,&m.a,&m.b,&m.c);

//给某个成员赋值,会影响到另外得成员

//左边是高位,右边是低位

//高位放高地址,低位放低地址

m.c = 0x44332211;

printf("m.c = %x\n",m.c);

printf("m.a = %x\n", m.a);

printf("m.b = %x\n", m.b);

m.a = 00;

printf("m.c = %x\n", m.c);

printf("m.a = %x\n", m.a);

printf("m.b = %x\n", m.b);

system("pause");

}

未完,待续...

`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值