C语言-结构体(struct)

一、引言:

若要定义一个变量,可以使用 C语言提供的基本数据类型(int、char等);如果需要定义多个相同变量(N:1),可以使用数组完成;如果需要定义多个不同变量(N:M),此时 C语言己经无法逐个给出定义,于是放开自定义权限,struct关键字就应运而生了。


二、结构体定义、访问、赋值

请看下面例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student               //定义结构体
{
	char name[100];
	int age;
	char sex;
	int score;
}stu;
int main()
{
	stu s1;
	stu *p = &s1;
	strcpy(s1.name, "ZhangSan");	//不能直接赋值
	s1.age = 19;
	s1.sex = 'f';
	s1.score = 98;
	//若使用键盘输入,%c前留个空格,防止读入回车
	//scanf("%s%d %c%d", s1.name, &s1.age, &s1.sex, &s1.score);
	printf("%s\t", s1.name);	//点成员运算符
	printf("%d\t", s1.age);
	printf("%c\t", s1.sex);
	printf("%d\n", s1.score);
	printf("----------------------------------\n");
	printf("%s\t", p->name);	//指向成员运算符
	printf("%d\t", p->age);
	printf("%c\t", p->sex);
	printf("%d\n", p->score);
	system("pause");
	return 0;
}

注意几个问题:

        1、给s1.name不能直接赋值(s1.name = “ZhangSan”;),因为s1.name本质是数组名,是个常量不能赋值。可以使用字符串拷贝的方式。

        2、初始化和赋值不同:数组定义时可以初始化(char name[30] = "ZhangSan";合法),定义后不能直接赋值,这是由于初始化使用的是一种特殊语法。

        3、两个凡是:凡是基本类型,既可定义时初始化,也可定义后赋值;凡是构造类型,要么在定义时就初始化,不能先定义再以初始化的方式赋值。


三、结构体数组:

本质就是一维数组,其成员是结构体。

结构体嵌套:结构体中,又嵌套结构体。

结构体之间赋值:相同类型结构体变量之间可以赋值,不同类型不可以。

用途:传参和返回(传地址效率高)

typedef struct student  
{
	char name[100];
	int age;
}stu;
int main()
{
	stu s1 = { { "Jack" }, 20 };
	stu s2;
	s2 = s1;      //相同类型结构体可以实现互相之间赋值
	printf("name:%s	age:%d\n", s2.name, s2.age);
	system("pause");
	return 0;
}

四、结构体大小:

由于存在内存对齐,因此结构体实际大小比结构体内所有变量所占内存之和大。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student             
{
	int age;        //4个字节
	char sex;	//1个字节
	float score;    //8个字节
}stu;
int main()
{
	stu s1;
	printf("%d\n", sizeof(stu));    //结果为12
	printf("%d\n", sizeof(s1));     //结果为12
	system("pause");
	return 0;
}

五、结构体使用注意事项:

1、向结构体内未初始化的指针拷贝。

情形一:name指针没有初始化,并没有指向一个合法的地址

struct student
{
    char *name;          //未初始化
    int score;
}stu;
int main()
{
    /*可以这样解决:
    stu.name = (char *)malloc(100);*/
    strcpy(stu.name,"Jim");  //name 指针并没有指向一个合法的地址
    stu.score = 99;
    /*free(stu.name);
    stu.name = NULL;*/
    return 0;
}

情形二:为指针变量pstu分配了内存,但是同样没有给name指针分配内存。错误与上面第一种情况一样。这里用了一个 malloc给人一种错觉,以为也给name指针分配了内存。

typedef struct student
{
	char *name;  //同样未初始化
	int score;
}stu;
int main()
{
	stu *pstu;
	pstu = (stu*)malloc(sizeof(stu));  //给结构体开辟了空间
	strcpy(pstu->name, "Jimy");
	pstu->score = 99;
	free(pstu);
	return 0;
}
	

2、未释放结构体内指针所指向的空间。

typedef struct student
{
	char*name;
	int score;
}Stu;
int main()
{
	Stu * p = (Stu*)malloc(sizeof(Stu));
	p->name = (char *)malloc(100);
	strcpy(p->name, "ZhangSan");
	p->score = 200;
	free(p->name); //这个地方注意,要由内而外的释放空间
	free(p);
	return 0;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值