C/C++心得-结构体
先说句题外话,个人认为,基本上所有的高级语言被设计出来的最终目的是降低软件开发难度,提升软件开发人员素质和团队协作能力,降低软件维护的难度。在学习语言的时候,可以从这么方面来推测各种语言语法设计的原因,从来更好的掌握各种编程语言。
总结一下C语言中的数据类型结构:
1.常用基本数据类型(int, char, float, double, short, long等等)
2.数组
3.指针
4.枚举
5.结构体
6.公用体
...
这其中除了共用体不常用外,其他都是实际开发中经常用到的数据结构。其他的之前两篇都有说明,今天来说说枚举和结构体。
(初学者应该养成读代码从main开始读的习惯)
1.枚举
枚举作为一种数据类型,用于声明一组命名的常数,用来说明一种事物的不同类型或属性。实际应用作用的话,个人认为是提高代码的可读性,减小程序的维护难度。
举个例子,一个程序中需要使用变量表示颜色,那么写程序前我们需要先设定标准:0表示白色,1表示红色,2表示黄色,3表示蓝色...,那么程序代码如下:
#include <stdio.h>
#include <stdlib.h> void printColor(int color)
{
switch (color)
{
case :
printf("白色\n");
break;
case :
printf("红色\n");
break;
case :
printf("黄色\n");
break;
case :
printf("蓝色\n");
break;
default:
break;
}
} int main(int arg, char *args)
{
int color0 = ; // 白色
int color1 = ; // 红色
int color2 = ; // 黄色
int color3 = ; // 蓝色 printColor(color0);
printColor(color1);
printColor(color2);
printColor(color3); getchar();
return ;
}
(关于枚举的例子只是作为说明,这些作为例子有些不太好)如果程序代码量很大的情况下,0,1,2,3的这种数字意义很容易忘记,这时可以用到枚举
#include <stdio.h>
#include <stdlib.h> enum Color
{
White, // 白色
Red, // 红色
Yellow,// 黄色
Blue // 蓝色
}; void printColor(int color)
{
switch (color)
{
case White:
printf("白色\n");
break;
case Red:
printf("红色\n");
break;
case Yellow:
printf("黄色\n");
break;
case Blue:
printf("蓝色\n");
break;
default:
break;
}
}
int main(int arg, char *args)
{
int color0 = White; // 白色
int color1 = Red; // 红色
int color2 = Yellow; // 黄色
int color3 = Blue; // 蓝色 printColor(color0);
printColor(color1);
printColor(color2);
printColor(color3); getchar();
return ;
}
对枚举的理解应用暂时就如此,关于枚举的作为属性应用,以及其他方面的应用,有兴趣的可以查查其他资料。
2.结构体
结构体的意义之一同样是增加代码可读性。而且结构体配合指针使得C语言变得非常灵活。
结构体是由一系列具有相同或不同类型的数据组成。
下面用两种方法定义并输出一个学生的信息。
首先是不用结构体和枚举的方法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> int getSex(short sex, char * sexVal)
{
if (sexVal == NULL)
{
return -;
}
switch (sex)
{
case :
strcpy(sexVal, "男");
break;
case :
strcpy(sexVal, "女");
break;
default:
return -;
break;
}
return ;
}
// 不用结构体和枚举的方法
int main(int arg, char * args[])
{
int num = ;
char name[] = "LiLei";
short sexN = ;
char sex[] = { '\0' };
if (getSex(sexN, sex) != )
{
return -;
}
printf("学号:%d,姓名:%s,性别:%s\n", num, name, sex); getchar();
return ;
}
下面使用结构体和枚举改造代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef enum _Sex
{
Male,
Female
}Sex; struct Student
{
int num;
char name[];
short sex;
}; int getSex(Sex sex, char * sexVal)
{
if (sexVal == NULL)
{
return -;
}
switch (sex)
{
case Male:
strcpy(sexVal, "男");
break;
case Female:
strcpy(sexVal, "女");
break;
default:
return -;
break;
}
return ;
} int main(int arg, char * args[])
{
struct Student stu = { , "LiLei", Male };
char sex[] = { };
if (getSex(stu.sex, sex) != )
{
return -;
}
printf("学号:%d,姓名:%s,性别:%s\n", stu.num, stu.name, sex);
getchar();
return ;
}
可以发现,在没有什么注释的情况下,从Main开始读代码,第二段代码是比较好理解。
使用结构体一般都会使用typedef给结构体起个别名,当然typedef在指针、数组等方面都有应用,使用typedef可以精简代码。下面举个例子
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> enum Sex
{
Male,
Female
}; typedef struct _Student
{
long num;
char name[];
short sex;
} Student; // 使用typedef给结构体起别名 int main(int arg, char * args[])
{
struct _Student stu1 = { , "hel", Male }; // 不使用typedef前的定义方式
Student stu2 = { , "yao", Male }; // 使用typedef的定义方式,主要是省去一个struct return ;
}
typedef的用法,先正常定义,然后用别名替代掉原变量(或函数名)名称的位置,如:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef int mI;
typedef char mCh;
typedef char mStr[];// 原来定义char数组是 char * str[32]; 这里将str替换为别名
typedef int (* name)(int a, int b); // int sum(int a, int b), 因为函数需要以指针形式表示,所以把sum替换为 * name int sum(int a, int b)
{
return a + b;
} int main(int arg, char *args[])
{
mI num = ;
mCh ch = 'x';
mStr str = "hello"; // 这里相当于定义 char str[32] = "hello";
name func = sum; // 函数指针,相当于 int func(int a, int b); func中的执行代码和sum函数相同
printf("num:%d,a=%c,str=%s,func(1, 2)=%d\n", num, ch, str, func(, ));
getchar();
return ;
}
再说说结构体的长度。结构体的长度要略大于或等于其内部成员的总长度。主要是为了程序速度,在一个结构体内有多个类型的成员的时候,会做一些“对齐”处理,该处理有可能导致结构体变量占用空间变大。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> struct Student1
{
int num;
char name[];
short sex;
};
struct Student2
{
long long num;
char name[];
short sex;
}; int main(int arg, char * args[])
{
struct Student1 stu1;
struct Student2 stu2;
printf("int:%d, char:%d, short:%d, longlong:%d\n", sizeof(int), sizeof(char), sizeof(short), sizeof(long long)); // 比较4种数据类型的长度
printf("long:%d,int:%d\n", sizeof(struct Student2), sizeof(struct Student1)); // 比较两种结构体的长度
printf("stu1:%x,stu2:%x\n", &stu1, &stu2); // 两个结构体变量的地址
getchar();
return ;
}
上面这段程序的输出结构为:
int:, char:, short:, longlong:
long:,int:
stu1:eafeb4,stu2:eafe7c
从第一行输出信息来看,我们可以算出结构体Student1声明的变量(int num, char name[32], short sex)的总长度应该为38,而第二行的实际输出结果为40.
同样可以算出结构体Student2声明的变量(long long num, char name[32], short)的总长度应该为42,而实际结果为48.
一个结构体的长度必定是其内部长度最大基本数据类型元素的整数倍,上面Student1和Student2都符合该项(数组不是基本数据类型)。
而且结构体变量的首地址必定能被其内部长度最大基本数据类型元素整除,如上面eafeb4可以被4整除,eafe7c可以被8整除。
3.结构体的一点高级用法
1.通过地址取结构体内成员的值(代码作为示例,真实开发中应该不会这样写)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> enum Sex
{
Male,
Female
}; struct Student1
{
int num;
char name[];
short sex;
};
struct Student2
{
long long num;
char name[];
short sex;
}; int main(int arg, char * args[])
{
char * stu1Name = NULL;
char * stu2Name = NULL;
struct Student1 stu1 = { , "LiLei", Male };
struct Student2 stu2 = { , "WaLiu", Female }; printf("int:%d, char:%d, short:%d, longlong:%d\n", sizeof(int), sizeof(char), sizeof(short), sizeof(long long)); // 比较4种数据类型的长度
printf("long:%d,int:%d\n", sizeof(struct Student2), sizeof(struct Student1)); // 比较两种结构体的长度
printf("stu1:%x,stu2:%x\n", &stu1, &stu2); // 两个结构体变量的地址
printf("stu1:%x,stu2:%x\n", &stu1 + , &stu2 + ); stu1Name = (char *)(((char *)&stu1) + ); // 取stu1的地址,向后偏移4位,这个地址就是name的首地址,将其赋给stu1Name
stu2Name = (char *)(((char *)&stu2) + ); // 取stu2的地址,向后偏移8位,这个地址就是name的首地址,将其赋给stu2Name printf("stu1:%s,stu2:%s\n", stu1Name, stu2Name); // 打印出值
getchar();
return ;
}
以上代码执行结构为:
int:, char:, short:, longlong:
long:,int:
stu1:107fdb0,stu2:107fd70
stu1:107fe50,stu2:107ff30
stu1:LiLei,stu2:WaLiu
这说明可以通过地址偏移的方式取得结构体变量内部的值。
C/C++心得-结构体的更多相关文章
- CAN编写完分帧发送, 分帧接收,J1939位域型结构体心得
关于由多个不同的C文件构成的工程,我采用以下方法 以为400Hz数字电源程序为例 假设工程由以下文件组成 DC_Comm.c 主要完成串口通讯部分 DC_Config.c 主要完成时钟,外设 中断初始 ...
- c++ 数组 结构体
接下来的一点时间我将会记录下我看的c++的一些心得体会,人贵在坚持,希望我可以一直坚持下去!!Go Fighting! 一.c++复合数据类型: 数组类型的一些注意事项: sizeof的用法: 当 ...
- 漫谈C语言结构体
相信大家对于结构体都不陌生.在此,分享出本人对C语言结构体的学习心得.如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了.当然,水平有限,若发现不足之处恳请指出.代码文件test.c我放在 ...
- 漫谈C语言结构体【转】
相信大家对于结构体都不陌生.在此,分享出本人对C语言结构体的学习心得.如果你发现这个总结中有你以前所未掌握的,那本文也算是有点价值了.当然,水平有限,若发现不足之处恳请指出.代码文件test.c我放在 ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
- C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱
一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...
- go语言结构体
定义: 是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体. 成员: 每个值称为结构体的成员. 示例: 用结构体的经典案例处理公司的员工信息,每个员工信息包含一个唯一的员工编号.员工的名字. ...
- C语言中的结构体
用户自己建立自己的结构体类型 1. 定义和使用结构体变量 (1).结构体的定义 C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体. (2).声明一个结构体类型的一般形式为: ...
- C++_系列自学课程_第_12_课_结构体
#include <iostream> #include <string> using namespace std; struct CDAccount { double bal ...
随机推荐
- window.history,页面中的返回按钮
一.页面中的返回按钮事件 window.history可以不加window这个前缀 他的方法有: window.history.go(-1); //-n表示后退n页,n表示前进n页,或者是一个url ...
- Table Code
post.PostToTags.Where(t => tagArray.Contains(t.PostTag.Name, comparerWihtoutCases) && !t. ...
- 如何制作Win10系统U盘安装镜像
准备的工具: 1.空间8G以上的U盘一个 2.系统镜像文件(ISO格式)下载:https://msdn.itellyou.cn/ 3.UltraISO 下载:https://cn.ultraiso.n ...
- .net IoC 之 Spring.Net 适合刚开始使用
Spring.Net包括控制反转(IoC) 和面向切面(AOP),这篇文章主要说下IoC方面的入门. 一.首先建立一个MVC项目名称叫SpringDemo,然后用NuGet下载spring(我用的是S ...
- 设计模式入门,观察者模式,c++代码实现
// test02.cpp : Defines the entry point for the console application.////设计模式第2章 观察者模式#include " ...
- python2文件转换为exe可执行文件
windows下py文件的运行需要安装python,如果是exe文件就可以直接运行 1. 直接在命令行用pip安装 pyinstaller pip install pyinstaller 2 在命令行 ...
- ComfortColor.xcs
ComfortColor.xcs [comfort color] text=dce2e2text(bold)=dce2e2 magenta=dd3682magenta(bold)=dd3682 whi ...
- 2048小游戏4X4C语言
*/ #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> v ...
- svn 文件后面显示时间和提交人
1.在eclipse中选择window-->preferences,然后选择下图中的位置,就可以显示你想要的东西的了,在此记下以备后用
- 关于纯css写三角形在firefox下的锯齿问题
相信很多人都用过利用border来实现小三角箭头,百度一下,这类的文章多如牛毛,这里我还是啰嗦点把常用的方法陈列出来: .triangle_border_up{ width:; height:; bo ...