当前位置:网站首页>C语言结构体(必须掌握版)
C语言结构体(必须掌握版)
2022-08-04 05:31:00 【π指针】
本文–并没有—介绍结构体为什么是这样的,里面的内存分配(对于深入结构体来说非常重要),怎么写才是对内存空间最友好的。本文只适合快速区掌握一下怎么写,和对结构体的基本操作,指针对结构体的基本操作,和对结构体数组的基本操作。
结构体的学习内容
- 掌握结构体类型,变量的定义 和 初始化多种不同的写法
- 掌握结构体数组以及操作
- 掌握结构体指针以及操作
文章目录
一、多种定义方式的结构体
结构体类型的定义 结构体类型变量的定义 与 初始化
//这是结构体类型的定义
struct Stu{
char name[20];
int age;
float score;
};
//这是结构体类型变量的定义
struct Stu stu1;
//这是结构体类型变量的初始化
={
"nihao",100,1.11};
有多种结合方式
1.先声明结构体类型,然后定义类型的变量名,再初始化
int main(){
struct Stu{
char name[30];
int age;
float score;
};
//struct Stu stu1,stu2,stu3 可以很多个;
struct Stu stu1;
//后面再初始化的方式那就不可以一下子赋值了 stu1 = {" ",xxxx,xxxx);
//一旦是先定义类型,然后在定义类型变量,再初始化,那就不可以给字符串直接赋值了 ,和定义字符数组一样
//stu1.name = "ZhangSan"; 要用一些方法,比如字符串的复制
strcpy(stu1.name,"ZhangSan");
stu1.age = 19;
stu1.score = 100;
printf("%s %d %f\n",stu1.name,stu1.age,stu1.score);//ZhangSan 19 100.000000
return 0;
}
2.先声明结构体类型,然后定义类型变量名和立即初始化
int main(){
struct Stu{
char name[30];
int age;
float score;
};
//可以直接写字符
//struct Stu stu1={"LiSi",20,100.1},stu2={"WangWu,22,120"};
struct Stu stu1 = {
"LiSi",20,100.1};
printf("%s %d %.2f\n",stu1.name,stu1.age,stu1.score);//LiSi 20 100.10
return 0;
}
3.声明结构体类型时同时定义类型变量名,然后再初始化
int main(){
struct Stu{
char name[30];
int age;
float score;
}stu1,stu2;
//字符也不可以直接赋值了,要用某些方式如复制
//也不可以stu1 = {xxxx,xxx,xxxx};
strcpy(stu1.name,"LaoLiu");
stu1.age = 22;
stu1.score = 150;
printf("%s %d %.2f\n",stu1.name,stu1.age,stu1.score);//LaoLiu 22 150.00
return 0;
}
4.声明结构体类型时同时定义类型变量名和初始化
int main(){
struct Stu{
char name[30];
int age;
float score;
}stu1 = {
"LiSi",20,101},stu2 = {
"LiSi2",22,102};
printf("%s %d %.2f\n",stu1.name,stu1.age,stu1.score);//LiSi 20 101.00
printf("%s %d %.2f\n",stu2.name,stu2.age,stu2.score);//LiSi2 22 102.00
return 0;
}
5. 还有一种这种不推荐使用(没有结构体名),偏于一次性定义了下面就不可以再定义了
int main(){
//没有结构体名字的,就只能声明后立即定义了
struct{
char name[30];
int age;
float score;
}stu1 = {
"LiSi",20,101};
//或者下面在初始化也可以
//strcpy(stu1.name,"nihao");
//stu1.age = 19;
//stu1.score = 10000;
printf("%s %d %.2f\n",stu1.name,stu1.age,stu1.score);//LiSi 20 101.00
return 0;
}
二、结构体类型变量的引用
结构体要引用里面成员的值,引用方式为结构体变量名.成员.(点称为结构体成员运算符)它的优先级和括号是一模一样,下面都会间接式的用到
三、结构体数组
可以加中括号作为区分,也可以不加,程序都可以识别出来
int main(){
struct Stu{
char name[30];
int age;
}stu1[3]={
"ZhanSan",20,"LiSi",30,"WangWu",40};//{
{"ZhanSan",20},{"LiSi",30,"WangWu",40}};
struct Stu stu2[3]={
{
"ZhanSan",20},{
"LiSi",30},{
"WangWu",40}};
struct Stu stu3[2];
strcpy(stu3[0].name,"zhouliu");
stu3[0].age = 10;
strcpy(stu3[1].name,"zhouri");
stu3[1].age = 12;
printf("%s %d %s %d %s %d\n",stu1[0].name,stu1[0].age,stu1[1].name,stu1[1].age,stu1[2].name,stu1[2].age);//ZhanSan 20 LiSi 30 WangWu 40
printf("%s %d %s %d %s %d\n",stu2[0].name,stu2[0].age,stu2[1].name,stu2[1].age,stu2[2].name,stu2[2].age);//ZhanSan 20 LiSi 30 WangWu 40
printf("%s %d %s %d\n",stu3[0].name,stu3[0].age,stu3[1].name,stu3[1].age);//zhouliu 10 zhouri 12
return 0;
}
四、结构体指针
指向结构体的一个指针就像int a = 10; int *p = &a,这是指向一个a变量的一个指针,然后类型是int型
结构体指针说明
下面的例子,就代表指向一个结构体的指针,然后类型是struct Stu型
int main(){
struct Stu{
char name[30];
int age;
};
struct Stu stu1 = {
"zhangsan",20};
struct Stu *p = &stu1;
return 0;
}
通过代码了解到,指针p指向的是结构体的首地址,也是stu1.name的首地址由此,*p则等价于stu1,可以把他完全看成stu1来使用
int main(){
struct Stu{
char name[32];
int age;
};
struct Stu stu1 = {
"zhangsan",20};
struct Stu *p = &stu1;//相当于 p = &stu1;
printf("%X\n",p);//62FDF0
printf("%X\n",&stu1);//62FDF0
printf("%X\n",&stu1.name);//62FDF0
return 0;
}
结构体指针的操作1
作为结构体指针,有->可以使用,这个符号叫做"指向结构体成员运算符",优先级和括号,和(.点)是一样高的
int main(){
struct Stu{
char name[32];
int age;
};
struct Stu stu1 = {
"zhangsan",20};
struct Stu *p = &stu1;
//等价操作
printf("%s\n",(*p).name);//zhangsan
printf("%d\n",(*p).age);//20
printf("%s\n",stu1.name);//zhangsan
printf("%d\n",stu1.age);//20
printf("%s\n",p->name);//zhangsan
printf("%d\n",p->age);//20
printf("%s\n",(&stu1)->name);//zhangsan
printf("%d\n",(&stu1)->age);//20
return 0;
}
注意:
- 在操作p的时候加的括号,因为不加括号是一种错误操作了,因为.的优先级比高,解释为p.name先运行,这样就代表结构体变量名为p的,他的name是什么,然后找不到就报错了,如果找得到再运行星号*则又查看一下结构体里面这个name的值是不是存的地址,如果是则找到此地址对应的值打印出来,如果不是就报错
- 然而这个->就是为了防止这种错误操作而使用的,而且也是一种很友好的标志。
- (*p). 等价于 stu1. 等价于 p→等价于(&stu1) →
结构体指针的操作2
int main(){
struct Stu{
char name[32];
int age;
};
struct Stu stu1[3] = {
{
"zhangsan",20},{
"LISI",20},{
"wangwu",39}};
struct Stu *p = &stu1;
int i;
for(i=0;i<3;i++,p++){
printf("%s %d\n",p->name,p->age);
}
return 0;
}
运行结果如下:
//zhangsan 20
//LISI 20
//wangwu 39
总结
- p在指向&stu1的时候,指向了stu1的首地址,也就是stu1[0]的地址(确切点是stu1[0].name的地址,但是这里不展开)那么p+1的时候,+1指加了一个结构体单元,这里又36个字节。指到了stu1[1]这里
五、结构体的应用
下面是使用结构体的一种典型例子(链表)-在数据结构与算法中结构体看到的居多
#include <stdio.h>
#include <stdlib.h>
struct Stu{
int data;
struct Stu *node;
};
//初始化头节点
struct Stu * initList(struct Stu *L){
L = (struct Stu *)malloc(sizeof(struct Stu));//开辟了一个结构体大小的内存,然后把首地址赋给了名字叫node节点 ;
L->data = 0;
L->node = NULL;
return L;
}
//插入节点
int insertList(struct Stu *L,int num){
struct Stu *p = (struct Stu *)malloc(sizeof(struct Stu));
if(p == NULL) return 0;
p->data = num;
p->node = NULL;
L->node = p;
p = NULL;//p指向NULL;
return 1;
}
int main(){
//定义一个节点
struct Stu *N = NULL;
N = initList(N);//初始化头节点
int flag = insertList(N,3);//从头结点添加节点(头插)
if(flag){
printf("插入成功\n");
}else{
printf("插入失败\n");
}
//还有删除节点,查询节点等之类的就不一样介绍了,用法就这样使用的 (在小编的数据结构与算法中有这一节的优化版,且齐全)
return 0;
}
六、致读者
有缘读到此文章的您若发现此文章有错误或需要改进的地方,能够果断的提出是我的福气,谢谢各位。
边栏推荐
- 【五一专属】阿里云ECS大测评#五一专属|向所有热爱分享的“技术劳动者”致敬#
- 如何成长为高级工程师?
- tensorRT教程——使用tensorRT OP 搭建自己的网络
- LeetCode_Nov_2nd_Week
- 彻底删除MySQL教程
- Rules.make-适合在编辑模式下看
- MNIST Handwritten Digit Recognition - Building a Perceptron from Zero for Two-Classification
- Tencent and NetEase have taken action one after another. What is the metaverse that is so popular that it is out of the circle?
- 【深度学习日记】第一天:Hello world,Hello CNN MNIST
- [Copy Siege Lion Log] Flying Pulp Academy Intensive Learning 7-Day Punch Camp-Study Notes
猜你喜欢
IDEA创建Servlet步骤
TensorRT 5 初步认识
[CV-Learning] Linear Classifier (SVM Basics)
arm交叉编译
MNIST handwritten digit recognition, sorted by from two to ten
MNIST Handwritten Digit Recognition - Building a Perceptron from Zero for Two-Classification
The second official example analysis of the MOOSE platform - about creating a Kernel and solving the convection-diffusion equation
安装Apache服务时出现的几个问题, AH00369,AH00526,AH00072....
深度学习,“粮草”先行--浅谈数据集获取之道
度量学习(Metric learning、损失函数、triplet、三元组损失、fastreid)
随机推荐
arm-3-中断体系结构
第三章 标准单元库(上)
Chapter One Introduction
LeetCode_22_Apr_4th_Week
Completely remove MySQL tutorial
lstm pipeline 过程理解(输入输出)
AWS使用EC2降低DeepRacer的训练成本:DeepRacer-for-cloud的实践操作
AWS uses EC2 to reduce the training cost of DeepRacer: DeepRacer-for-cloud practical operation
LeetCode_Nov_5th_Week
Amazon Cloud Technology Build On-Amazon Neptune's Knowledge Graph-Based Recommendation Model Building Experience
tmux概念和使用
【Copy攻城狮日志】飞浆学院强化学习7日打卡营-学习笔记
[日常办公][ssh]cheatsheet
学习资料re-id
度量学习(Metric learning)—— 基于分类损失函数(softmax、交叉熵、cosface、arcface)
关于DG(域泛化)领域的PCL方法的代码实例
Copy Siege Lions "sticky" to AI couplets
Tencent and NetEase have taken action one after another. What is the metaverse that is so popular that it is out of the circle?
MNIST手写数字识别 —— 从二分类到十分类
机器学习——分类问题对于文字标签的处理(特征工程)