当前位置:网站首页>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;
}
六、致读者
有缘读到此文章的您若发现此文章有错误或需要改进的地方,能够果断的提出是我的福气,谢谢各位。
边栏推荐
- MOOSE平台官方第二个例子分析——关于创建Kernel,求解对流扩散方程
- 在AWS-EC2中安装Minikube集群
- 【Copy攻城狮日志】“一分钟”跑通MindSpore的LeNet模型
- Rules.make-适合在编辑模式下看
- Amazon Cloud Technology Build On-Amazon Neptune's Knowledge Graph-Based Recommendation Model Building Experience
- 集合--LinkedList
- 题目1000:输入两个整数a和b,计算a+b的和,此题是多组测试数据
- The second official example analysis of the MOOSE platform - about creating a Kernel and solving the convection-diffusion equation
- LeetCode_22_Apr_4th_Week
- 第三章 标准单元库(下)
猜你喜欢
MOOSE平台使用入门攻略——如何运行官方教程的例子
tensorRT教程——tensor RT OP理解(实现自定义层,搭建网络)
arm学习-1-开发板
Thunderbolt turns off automatic updates
target has libraries with conflicting names: libcrypto.a and libssl.a.
【论文阅读】SPANET: SPATIAL PYRAMID ATTENTION NETWORK FOR ENHANCED IMAGE RECOGNITION
中国联通、欧莱雅和钉钉都在争相打造的秘密武器?虚拟IP未来还有怎样的可能
安装MySQL的详细步骤
Deep Learning Theory - Overfitting, Underfitting, Regularization, Optimizers
MNIST handwritten digit recognition, sorted by from two to ten
随机推荐
【论文阅读】Further Non-local and Channel Attention Networks for Vehicle Re-identification
题目1000:输入两个整数a和b,计算a+b的和,此题是多组测试数据
LeetCode_22_Apr_4th_Week
MNIST手写数字识别 —— 从零构建感知机实现二分类
LeetCode_22_Apr_2nd_Week
How to get started with MOOSE platform - an example of how to run the official tutorial
Windows10重置MySQL用户密码
arm-2-基础阶段
[开发杂项][VS Code]remote-ssd retry failed
[日常办公][杂项][vscode]tab space
AWS使用EC2降低DeepRacer的训练成本:DeepRacer-for-cloud的实践操作
No matching function for call to ‘RCTBridgeModuleNameForClass‘
MVC自定义配置
TensorRT 5 初步认识
代码庆端午--粽你心意
2020-03-27
yoloV5 使用——训练速度慢,加速训练
安装MySQL的详细步骤
LeetCode_Nov_5th_Week
arm学习-1-开发板