C_10_结构体

结构体

结构体中 只要遇到 字符串的 就用 strcpy 进行操作不用 = 因为等号是进行的浅拷贝 只是将地址进行复制而不是复制对象本身

1 作用

> 结构体是一种构造类型的数据结构,
	是一种或多种基本类型或构造类型的数据的集合

2 定义结构体

语法1

struct 结构体名
{
// 定义变量
};

语法2:

定义结构体时顺带创建一个结构体变量

struct 结构体名
{
	// 定义变量
}结构体变量名;

语法3:

给结构体起别名

typedef struct 结构体名称
{
// 定义成员变量
// 可以定义无数个成员变量
}别名;

语法4:

struct{
	// 定义成员变量
	// 可以定义无数个成员变量
} 结构体变量名;

3 创建结构体变量

语法1:

struct 结构体名称 结构体变量 = {1,2,3,....};
struct 结构体名称 结构体变量;

语法2:

> 别名 结构体变量 = {值1,值2,值3,....};
> 别名 结构体变量;

注意:

# 结构体对象清0
#				memset(&结构体变量名,0,sizeof(struct 结构体名称));
    结构体初始化 必须按照成员顺序和成员自身类型

4 结构体变量使用其中成员变量

存值
		结构体变量.成员变量名 = 值;
		注意:字符串的成员变量需要使用strcpy实现深拷贝
取值
		结构体变量.成员变量名

5 计算结构体大小

> 对齐方式,默认按照最大的进行对齐
	数组,结构体将被拆分为存储的数据的大小

示例:

struct Stu
{
 short x;      // 4
 int a;        // 4
 char c;       // 4
 char str[50]; // 47 / 4 = 11 .. 3 = 12 * 4 = 48
};

6 强制对其

作用

		默认的结构体的对齐方式是由其中最大的成员进行对齐的
		使用强制对齐就会使用强制的大小进行对齐

语法

#pragma pack (value)时的指定对齐值value为1 2 4 8

示例

#include <stdio.h>
#pragma pack(2)
struct Test
{
    int x;   // 4
    int *p;  // 8
    char c;  // 2
    short s; // 2
};
int main(int argc, char const *argv[])
{
    printf("%d\n", sizeof(struct Test));
    return 0;
}

特殊结构体

匿名结构体

特点

> 只能创建一个结构体变量

语法:

struct {

	成员变量;

}结构体变量名;

示例

#include <stdio.h>
#include <string.h>
struct
{
		int age;
		char color[30];
}ql;
int main(int argc, char const *argv[])
{
		ql.age = 8000;
		strcpy(ql.color,"黑");
		printf("年龄:%d\t颜色:%s\n",ql.age,ql.color);
		return 0;
}

整体赋值

> 结构体变量名1 = 结构体变量名2;
> 将结构体变量2的成员的值逐一赋值给结构体变量1的成员

memcpy****函数

作用:拷贝内存中的内容

语法

void *memcpy(void *dest, const void *src, size_t n);
	参数:
		dest:目标地址
		src:资源地址
		n:长度

结构体定义结构体变量

概念: 结构体A中的成员变量是结构体B的变量

示例:

#include <stdio.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
typedef struct person
{
     char name[50];
     char sex[10];
     int age;
     // 结构体中定义结构体变量
     Dog dog;
} Person;
int main(int argc, char const *argv[])
{
     Dog dog = {"旺财", "公", 3};
     // 将上面定义的结构体变量dog全赋值给p1中的成员变量dog
     Person p1 = {"来福", "男", 18, dog};
     dog.age = 13;
     printf("p1的姓名:%s\n", p1.name);
     printf("p1的性别:%s\n", p1.sex);
     printf("p1的年龄:%d\n", p1.age);
     printf("p1 dog的姓名:%s\n", p1.dog.name);
     printf("p1 dog的性别:%s\n", p1.dog.sex);
     printf("p1 dog的年龄:%d\n", p1.dog.age);
     printf("dog的姓名:%s\n", dog.name);
     printf("dog的性别:%s\n", dog.sex);
     printf("dog的年龄:%d\n", dog.age);
     Person p2 = {"常威", "男", 28, {"黑豹", "母", 4}};
     printf("p2的姓名:%s\n", p2.name);
     printf("p2的性别:%s\n", p2.sex);
     printf("p2的年龄:%d\n", p2.age);
     printf("p2 dog的姓名:%s\n", p2.dog.name);
     printf("p2 dog的性别:%s\n", p2.dog.sex);
     printf("p2 dog的年龄:%d\n", p2.dog.age);
     return 0;
}

计算结构体大小

成员变量是结构体其占据的大小也是参与计算对齐单行大小的依据

#include <stdio.h>
typedef struct Data1
{
     char c; // 1
     int a;  // 4 8
     long b; //   8
} D1;       // 16
typedef struct Data2
{
     char c;  //  1
     int i;   //  4
     short s; //  2     16
     D1 d1;   // 16
} D2;
// 16+16 = 32
int main(int argc, char const *argv[])
{
     printf("%d\n", sizeof(D2));
     return 0;
}

结构体指针

概念

指向结构体变量的指针。

语法:

> 结构体名称 *指针变量名;

操作成员变量

指针变量名->成员变量名

指针变量名->成员变量名 = 值;

注意:

	字符数组型需要使用strcpy

示例

#include <stdio.h>
typedef struct stu
{
    char name[50]; // 48
    char sex[10];  // 12
    int age;       // 4
} Stu;
void chang01(Stu s)
{
    s.age = 29;
}
void chang02(Stu *s)
{
    s->age = 29;
}
int main(int argc, char const *argv[])
{
    Stu s01 = {"张三", "男", 18};
    Stu *p = &s01;
    printf("%s\n", p->name);
    p->age = 19;
    printf("%d\n", p->age);
    printf("%d\n", s01.age);
    // chang01(s01);//全赋值
    chang02(&s01); // 传递的是地址
    printf("%d\n", s01.age);
    return 0;
}

指针作为结构体成员

示例1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu
{
     char *name;
     char *sex;
     int age;
} Stu;
int main(int argc, char const *argv[])
{
     char str01[] = "Tom";
     char str02[] = "man";
     // Stu s = {str01,str02,19};
     // printf("s name = %s\n",s.name);
     // s.name[0] = 't';
     // printf("str01 = %s\n",str01);
     // printf("s name = %s\n",s.name);
     // 成员变量位指针变量如何实现深拷贝
     Stu s02;
     s02.name = calloc(50, 1);
     strcpy(s02.name, str01);
     s02.sex = calloc(10, 1);
     strcpy(s02.sex, str02);
     s02.age = 18;
     printf("s02 name = %s\n", s02.name);
     s02.name[0] = 't';
     printf("str01 = %s\n", str01);
     printf("s name = %s\n", s02.name);
     free(s02.name);
     free(s02.sex);
     return 0;
}

示例2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu
{
     char *name;
     char *sex;
     int age;
} Stu;
int main(int argc, char const *argv[])
{
     Stu *s01 = (Stu *)malloc(sizeof(Stu));
     s01->name = (char *)malloc(50);
     s01->sex = (char *)malloc(10);
     memset(s01, 0, sizeof(Stu));
     memset(s01->name, 0, 50);
     memset(s01->sex, 0, 10);
     strcpy(s01->name, "张三");
     strcpy(s01->sex, "男");
     s01->age = 20;
     printf("姓名:%s\t性别:%s\t年龄:%d\n", s01->name, s01->sex, s01->age);
     // 如果成员变量是指针,并且是动态开辟内存
     // 此时如果直接释放该结构体变量会导致内存泄漏
     // 所以应该先释放里面的成员变量的动态内存,在释放结构体变量的动态内存
     free(s01->name);
     free(s01->sex);
     free(s01);
     return 0;
}

示例3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char *name;
     char *sex;
     int age;
} Dog;
typedef struct person
{
     char *name;
     char *sex;
     int age;
     Dog *dog;
} Person;
int main(int argc, char const *argv[])
{
     Dog *d = (Dog *)calloc(1, sizeof(Dog)); // int d = 1;
     d->name = (char *)calloc(50, 1);
     d->sex = (char *)calloc(10, 1);
     Person *p = (Person *)calloc(1, sizeof(Person));
     p->name = (char *)calloc(50, 1);
     p->sex = (char *)calloc(10, 1);
     p->dog = d; // p->dog = d
     Person *p2 = (Person *)calloc(1, sizeof(Person));
     p2->name = (char *)calloc(50, 1);
     p2->sex = (char *)calloc(10, 1);
     p2->dog = d;
     free(d->name);
     free(d->sex);
     free(d);
     free(p->name);
     free(p->sex);
     free(p);
     free(p2->name);
     free(p2->sex);
     free(p2);
     return 0;
}

数组存储结构体变量

示例1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
int main(int argc, char const *argv[])
{
     Dog d01 = {"旺财01", "公", 2};
     Dog d02 = {"旺财02", "公", 2};
     Dog d03 = {"旺财03", "公", 2};
     Dog ds[] = {d01, d02, d03};
     int len = sizeof(ds) / sizeof(ds[0]);
     for (int i = 0; i < len; i++)
     {
printf("姓名:%s\t性别:%s\t年
龄:%d\n",ds[i].name,ds[i].sex,ds[i].age);
     }
     return 0;
}

示例2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
int main(int argc, char const *argv[])
{
     Dog d01 = {"旺财01", "公", 2};
     Dog d02 = {"旺财02", "公", 2};
     Dog d03 = {"旺财03", "公", 2};
     Dog *ds[] = {&d01, &d02, &d03};
     int len = sizeof(ds) / sizeof(ds[0]);
     for (int i = 0; i < len; i++)
     {
           printf("姓名:%s\t性别:%s\t年龄:%d\n", ds[i]->name, ds[i] - > sex, ds[i]->age);
     }
     return 0;
}

示例3

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
int main(int argc, char const *argv[])
{
     Dog *d01 = (Dog *)calloc(1, sizeof(Dog));
     strcpy(d01->name, "旺财01");
     strcpy(d01->sex, "公");
     d01->age = 2;
     Dog *d02 = (Dog *)calloc(1, sizeof(Dog));
     strcpy(d02->name, "旺财02");
     strcpy(d02->sex, "公");
     d02->age = 2;
     Dog *d03 = (Dog *)calloc(1, sizeof(Dog));
     strcpy(d03->name, "旺财03");
     strcpy(d03->sex, "公");
     d03->age = 2;
     Dog *ds[] = {d01, d02, d03};
     Dog **dss = &ds;
     for (int i = 0; i < 3; i++)
     {
           printf("姓名:%s\t性别:%s\t年龄:%d\n", dss[i]->name, dss[i] - > sex, dss[i]->age);
           free(dss[i]);
     }
     return 0;
}

示例4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
Dog **getDogs()
{
     static Dog *dogs[10] = {0};
     for (int i = 0; i < 10; i++)
     {
           char name[30] = "旺财";
           sprintf(name, "旺财%d", i + 1);
           dogs[i] = (Dog *)calloc(1, sizeof(Dog));
           strcpy(dogs[i]->name, name);
           strcpy(dogs[i]->sex, "公");
           dogs[i]->age = 2;
     }
     return &dogs;
}
int main(int argc, char const *argv[])
{
     Dog **dogs = getDogs();
     for (int i = 0; i < 10; i++)
     {
           printf("姓名:%s\n", dogs[i]->name);
     }
     return 0;
}

示例5

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct dog
{
     char name[50];
     char sex[10];
     int age;
} Dog;
Dog **getDogs()
{
     Dog **dogs = (Dog **)calloc(10, sizeof(Dog *));
     for (int i = 0; i < 10; i++)
     {
           Dog *d = (Dog *)calloc(1, sizeof(Dog));
           char n[30] = {0};
           sprintf(n, "旺财%d", i + 1);
           strcpy(d->name, n);
           printf("d = %p\n", d);
           dogs[i] = d;
     }
     return dogs;
}
int main(int argc, char const *argv[])
{
     Dog **dogs = getDogs();
     for (int i = 0; i < 10; i++)
     {
           printf("姓名:%s\n", dogs[i]->name);
     }
     for (int i = 0; i < 10; i++)
     {
           free(dogs[i]);
     }
     free(dogs);
     return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值