完美结构体数组定义和使用是什么意思

我们都知道C语言中变量的类型决萣了变量存储占用的空间当我们要使用一个变量保存年龄时可以将其声明为int类型,当我们要使用一个变量保存某一科目的考试成绩时可鉯将其声明为float

那么,当我们要做一个学生信息管理系统时需要保存学生的姓名、学号、年龄等信息,该怎么做呢

如当要保存三个学苼的信息时,

显然方法二跟更清晰,因为它把name、num、age都集成在一个模板要用的时候只要套用模板进行创建即可。这就是结构体

结构体(struct)昰由一系列具有相同类型或不同类型的数据项构成的数据集合,这些数据项称为结构体的成员如上面的student结构体包含三个成员,分别是name、num、age

结构体是C语言中的一种构造类型。C语言的数据类型如下图:

三、结构体变量的定义方法

此处student是结构体名,该名字是由任意定义的泹是尽量起个有意义的名称。其相当于一个模板可以使用这个模板去定义变量stu1,stu2stu3。定义的时候不要忘了struct

相对于方法一,此处省略了結构体名虽然更简洁了,但是因为没有了名字后面就不能用该结构定义新的变量。

student定义一个别名student关于typedef的介绍移步至往期笔记:【C语訁笔记】#define与typedef的区别?进行查看使用typedef给结构体创建一个别名,这在实际编程用使用非常广泛如STM32单片机固件库中,使用得很多如下图:

初始化变量和数组如下:

结构体变量是否也可以这样初始化?是的可以。与初始化数组的语法类似:

简而言之我们使用在一对花括号Φ括起来的初始化列表进行初始化,各初始化项用逗号分隔

为了让初始化项与结构中各成员的关联更加明显,我们让每个成员的初始化項独占一行这样做只是为了提高代码的可读性,对编译器而言只需要用逗号分隔各成员的初始化项即可。

C99C11为结构提供了指定初始化器(designated initializer)其初始化器使用点运算符和成员名。例如只初始化student结构中的name成员,可以这样做:

也可以按照任意顺序使用指定初始化器:

另外对特定成员的最后一次赋值才是它实际获得的值。例如考虑如下代码:

此时,赋给num的值应该是1314因为它在结构声明中紧跟在name成员之后。新值1314取代了之前的520

结构体成员的访问需要借助结构体成员运算符——点(.)。如:

/* 给结构体变量stu1的成员进行赋值 */

结构体是一块很重要嘚内容用得很多。关于结构体的内存对齐可查看往期笔记:【C语言笔记】C语言结构体内存对齐问题

以上就是关于结构体的一些笔记如囿错误欢迎指出。谢谢!

C 语言是一门抽象的、面向过程的語言C 语言广泛应用于底层开发,C 语言在计算机体系中占据着不可替代的作用可以说 C 语言是编程的基础,也就是说不管你学习任何语訁,都应该把 C 语言放在首先要学的位置上

下面这张图更好的说明 C 语言的重要性

可以看到,C 语言是一种底层语言是一种系统层级的语言,操作系统就是使用 C 语言来编写的比如 Windows、Linux、UNIX 。如果说其他语言是光鲜亮丽的外表那么 C 语言就是灵魂,永远那么朴实无华

那么,既然 C 語言这么重要它有什么值得我们去学的地方呢?我们不应该只因为它重要而去学我们更在意的是学完我们能学会什么,能让我们获得什么

C 语言是 1972 年,由贝尔实验室的丹尼斯·里奇(Dennis Ritch)肯·汤普逊(Ken Thompson)在开发 UNIX 操作系统时设计了C语言C 语言是一门流行的语言,它把计算机科学理論和工程实践理论完美的融合在一起使用户能够完成模块化的编程和设计。

计算机科学理论:简称 CS、是系统性研究信息与计算的理论基礎以及它们在计算机系统中如何实现与应用的实用技术的学科

C 语言是一门高效性语言,它被设计用来充分发挥计算机的优势因此 C 语言程序运行速度很快,C 语言能够合理了使用内存来获得最大的运行速度

C 语言是一门具有可移植性的语言这就意味着,对于在一台计算机上編写的 C 语言程序可以在另一台计算机上轻松地运行从而极大的减少了程序移植的工作量。

    ? C 语言是一门简洁的语言因为 C 语言设计更加靠近底层,因此不需要众多 Java 、C# 等高级语言才有的特性程序的编写要求不是很严格。

    ? C 语言具有丰富的数据类型不仅包含有传统的字符型、整型、浮点型、数组类型等数据类型,还具有其他编程语言所不具备的数据类型比如指针。

    ? C 语言能够直接对内存地址进行读写洇此可以实现汇编语言的主要功能,并可直接操作硬件

下面让我们通过一个简单的示例来说明一下 C 语言~

下面我们来看一个很简单的 C 语言程序,我是 mac 电脑所以我使用的是xcode进行开发,我觉得工具无所谓大家用着顺手就行

你可能不知道这段代码是什么意思,不过别着急我們先运行一下看看结果。

这段程序输出了Hello,World!My Name is cxuan最后一行是程序的执行结果,表示这段程序是否有错误下面我们解释一下各行代码的含义。

首先第一行的#include <stdio.h>, 这行代码包含另一个文件这一行告诉编译器把stdio.h的内容包含在当前程序中。stdio.h是 C 编译器软件包的标准部分它能够提供鍵盘输入和显示器输出。

什么是 C 标准软件包C 是由 Dennis M 在1972年开发的通用,过程性命令式计算机编程语言。

我们后面会介绍 stdio.h 现在你知道它是什么就好。

C 程序能够包含一个或多个函数函数是 C 语言的根本,就和方法是 Java 的基本构成一样

main()表示一个函数名,int表示的是 main 函数返回一个整數

这些我们后面也会详细说明,只需要记住 int 和 void 是标准ANSI C定义 main() 的一部分(如果使用 ANSI C 之前的编译器请忽略 void)。

然后是/*一个简单的 C 语言程序*/表示的昰注释注释使用/**/来表示,注释的内容在两个符号之间这些符号能够提高程序的可读性。

注意:注释只是为了帮助程序员理解代码的含義编译器会忽略注释

下面就是{,这是左花括号它表示的是函数体的开始,而最后的右花括号}表示函数体的结束{ }中间是书写代码的地方,也叫做代码块

printf(Hello,world!\n);表示调用一个函数,这个语句使用printf()函数在屏幕上显示Hello,world, printf() 函数是 C 标准库函数中的一种它能够把程序运行的结果输出箌显示器上。而代码\n表示的是换行也就是另起一行,把光标移到下一行

然后接下来的一行 printf() 和上面一行是一样的,我们就不多说了最後一行 printf() 有点意思,你会发现有一个%d的语法它的意思表示的是使用整形输出字符串。

代码块的最后一行是return 0它可以看成是 main 函数的结束,最後一行是代码块}它表示的是程序的结束。

好了我们现在写完了第一个 C 语言程序,有没有对 C 有了更深的认识呢肯定没有。。这才哪箌哪继续学习吧。

现在我们可以归纳为 C 语言程序的几个组成要素,如下图所示

C 语言程序成为高级语言的原因是它能够读取并理解人们嘚思想然而,为了能够在系统中运行hello.c程序则各个 C 语句必须由其他程序转换为一系列低级机器语言指令。这些指令被打包作为可执行对潒程序存储在二进制磁盘文件中。目标程序也称为可执行目标文件

在 UNIX 系统中,从源文件到对象文件的转换是由编译器执行完成的

gcc 编譯器驱动从源文件读取hello.c,并把它翻译成一个可执行文件hello这个翻译过程可用如下图来表示

这就是一个完整的 hello world 程序执行过程,会涉及几个核惢组件:【预处理器、编译器、汇编器、连接器】下面我们逐个击破。

预处理器会根据开始的#字符修改源 C 程序。#include <stdio.h>命令就会告诉预处理器去读系统头文件stdio.h中的内容并把它插入到程序作为文本。

然后就得到了另外一个 C 程序hello.i这个程序通常是以.i为结尾。

它包含的 17 个字节是函數 main 的指令编码如果我们在文本编辑器中打开 hello.o 将会看到一堆乱码。

我们的 hello 程序会调用printf函数它是 C 编译器提供的 C 标准库中的一部分。

printf 函数位於一个叫做printf.o文件中它是一个单独的预编译好的目标文件,而这个文件必须要和我们的 hello.o 进行链接连接器(ld)会处理这个合并操作。

结果是hello 攵件,它是一个可执行的目标文件(或称为可执行文件)已准备好加载到内存中并由系统执行。

对于上面这种简单的 hello 程序来说我们可鉯依赖编译系统(compilation system)来提供一个正确和有效的机器代码。然而对于我们上面讲的程序员来说,编译器有几大特征你需要知道

现代编译器是一種高效的用来生成良好代码的工具对于程序员来说,你无需为了编写高质量的代码而去理解编译器内部做了什么工作

然而,为了编写絀高效的 C 语言程序我们需要了解一些基本的机器码以及编译器将不同的 C 语句转化为机器代码的过程。

在我们的经验中一些非常复杂的錯误大多是由链接阶段引起的,特别是当你想要构建大型软件项目时

为了理解 hello 程序在运行时发生了什么,我们需要首先对系统的硬件有┅个认识

下面这是一张 Intel 系统产品的模型,我们来对其进行解释:

在整个系统中运行的是称为总线的电气管道的集合这些总线在组件之間来回传输字节信息。

通常总线被设计成传送定长的字节块也就是字(word)。

字中的字节数(字长)是一个基本的系统参数各个系统中都不盡相同。

现在大部分的字都是 4 个字节(32 位)或者 8 个字节(64 位)

Input/Output 设备是系统和外部世界的连接。

上图中有四类 I/O 设备:用于用户输入的键盘囷鼠标用于用户输出的显示器,一个磁盘驱动用来长时间的保存数据和程序

刚开始的时候,可执行程序就保存在磁盘上

控制器和适配器之间的主要区别在于封装方式。

控制器是 I/O 设备本身或者系统的主印制板电路(通常称作主板)上的芯片组

而适配器则是一块插在主板插槽上的卡。无论组织形式如何它们的最终目的都是彼此交换信息。

主存是一个临时存储设备而不是永久性存储,磁盘是永久性存儲的设备

主存既保存程序,又保存处理器执行流程所处理的数据从物理组成上说,主存是由一系列DRAM(dynamic random access memory)动态随机存储构成的集合

逻辑上說,内存就是一个线性的字节数组有它唯一的地址编号,从 0 开始

一般来说,组成程序的每条机器指令都由不同数量的字节构成C 程序變量相对应的数据项的大小根据类型进行变化。

CPU(central processing unit)或者简单的处理器是解释(并执行)存储在主存储器中的指令的引擎。

处理器的核心大尛为一个字的存储设备(或寄存器)称为程序计数器(PC)

在任何时刻PC 都指向主存中的某条机器语言指令(即含有该条指令的地址)。

从系统通电开始直到系统断电,处理器一直在不断地执行程序计数器指向的指令再更新程序计数器,使其指向下一条指令

处理器根据其指令集体系结构定义的指令模型进行操作。在这个模型中指令按照严格的顺序执行,执行一条指令涉及执行一系列的步骤

处理器从程序计数器指向的内存中读取指令,解释指令中的位执行该指令指示的一些简单操作,然后更新程序计数器以指向下一条指令

指令与指令之间可能连续,可能不连续(比如 jmp 指令就不会顺序读取)

下面是 CPU 可能执行简单操作的几个步骤:

? 加载(Load):从主存中拷贝一个字节或者┅个字到内存中覆盖寄存器先前的内容

? 存储(Store):将寄存器中的字节或字复制到主存储器中的某个位置,从而覆盖该位置的先前内容

? 操莋(Operate):把两个寄存器的内容复制到ALU(Arithmetic logic unit)把两个字进行算术运算,并把结果存储在寄存器中重写寄存器先前的内容。

算术逻辑单元(ALU)是对数芓二进制数执行算术和按位运算的组合数字电子电路

? 跳转(jump):从指令中抽取一个字,把这个字复制到程序计数器(PC)中覆盖原来的值

前面峩们简单的介绍了一下计算机的硬件的组成和操作,现在我们正式介绍运行示例程序时发生了什么我们会从宏观的角度进行描述,不会涉及到所有的技术细节~

刚开始时shell 程序执行它的指令,等待用户键入一个命令

当我们在键盘上输入了./hello这几个字符时,shell 程序将字符逐一读叺寄存器再把它放到内存中,如下图所示:

当我们在键盘上敲击回车键的时候shell 程序就知道我们已经结束了命令的输入。

然后 shell 执行一系列指令来加载可执行的 hello 文件这些指令将目标文件中的代码和数据从磁盘复制到主存。

一旦目标文件中 hello 中的代码和数据被加载到主存处悝器就开始执行 hello 程序的 main 程序中的机器语言指令。

这些指令将 hello,world\n 字符串中的字节从主存复制到寄存器文件再从寄存器中复制到显示设备,最終显示在屏幕上如下所示:

上面我们介绍完了一个 hello 程序的执行过程,系统花费了大量时间把信息从一个地方搬运到另外一个地方

hello 程序嘚机器指令最初存储在磁盘上。当程序加载后它们会拷贝到主存中。

当 CPU 开始运行时指令又从内存复制到 CPU 中。同样的字符串数据hello,world \n最初吔是在磁盘上,它被复制到内存中然后再到显示器设备输出。

从程序员的角度来看这种复制大部分是开销,这减慢了程序的工作效率因此,对于系统设计来说最主要的一个工作是让程序运行的越来越快。

由于物理定律较大的存储设备要比较小的存储设备慢。

而由於寄存器和内存的处理效率在越来越大所以针对这种差异,系统设计者采用了更小更快的存储设备称为高速缓存存储器(cache memory, 简称为 cache 高速缓存),作为暂时的集结区域存放近期可能会需要的信息。

图中我们标出了高速缓存的位置位于高速缓存中的L1高速缓存容量可以达到数万芓节,访问速度几乎和访问寄存器文件一样快

容量更大的L2高速缓存通过一条特殊的总线链接 CPU,虽然 L2 缓存比 L1 缓存慢 5 倍但是仍比内存要快 5 - 10 倍。

L1 和 L2 是使用一种静态随机访问存储器(SRAM)的硬件技术实现的

最新的、处理器更强大的系统甚至有三级缓存:L1、L2 和 L3。系统可以获得一个很大嘚存储器同时访问速度也更快,原因是利用了高速缓存的局部性原理

现在,我们来探讨一下入门级程序的细节由浅入深的来了解一丅 C 语言的特性。

我们上面说到#include<stdio.h>是程序编译之前要处理的内容,称为编译预处理命令

预处理命令是在编译之前进行处理。预处理程序一般以 号开头

所有的 C 编译器软件包都提供stdio.h文件。该文件包含了给编译器使用的输入和输出函数比如 println() 信息。

该文件名的含义是标准输入/输絀头文件通常,在 C 程序顶部的信息集合被称为头文件(header)

C 的第一个标准是由 ANSI 发布的。虽然这份文档后来被国际标准化组织(ISO)采纳并且 ISO 发布的修订版也被 ANSI 采纳了但名称 ANSI C(而不是 ISO C) 仍被广泛使用。一些软件开发者使用ISO C还有一些使用Standard C。

提供了一个名为assert的关键字它用于验证程序作出嘚假设,并在假设为假输出诊断消息

C 标准库的 ctype.h 头文件提供了一些函数,可以用于测试和映射字符

这些字符接受 int 作为参数,它的值必须昰EOF或者是一个无符号字符

EOF是一个计算机术语为 End Of File 的缩写,在操作系统中表示资料源无更多的资料可读取资料源通常称为档案或串流。通瑺在文本的最后存在此字符表示资料结束

C 标准库的errno.h头文件定义了整数变量errno,它是通过系统调用设置的这些库函数表明了什么发生了错誤。

C 标准库的float.h头文件包含了一组与浮点值相关的依赖于平台的常量

? limits.h头文件决定了各种变量类型的各种属性。定义在该头文件中的宏限淛了各种变量类型(比如 char、int 和 long)的值

? locale.h头文件定义了特定地域的设置,比如日期格式和货币符号

? math.h头文件定义了各种数学函数和一个宏在这个库中所有可用的功能都带有一个double类型的参数,且都返回double类型的结果

? signal.h头文件定义了一个变量类型sig_atomic_t、两个函数调用和一些宏来处悝程序执行期间报告的不同信号。

? stdarg.h头文件定义了一个变量类型va_list和三个宏这三个宏可用于在参数个数未知(即参数个数可变)时获取函數中的参数。

? stddef .h头文件定义了各种变量类型和宏这些定义中的大部分也出现在其它头文件中。

? stdlib .h头文件定义了四个变量类型、一些宏和各种通用工具函数

? string .h头文件定义了一个变量类型、一个宏和各种操作字符数组的函数。

? time.h头文件定义了四个变量类型、两个宏和各种操莋日期和时间的函数

main 函数听起来像是调皮捣蛋的孩子故意给方法名起一个主要的方法,来告诉他人他才是这个世界的中心但事实却不昰这样,而main()方法确实是世界的中心

C 语言程序一定从 main() 函数开始执行,除了 main() 函数外你可以随意命名其他函数。

通常main 后面的()中表示一些传叺信息,我们上面的那个例子中没有传递信息因为圆括号中的输入是 void 。

? void main() 声明了一个带有不确定参数的构造方法

它是指向 argc + 1 指针数组的第┅个元素的指针其中最后一个为null,而前一个(如果有的话)指向表示从主机环境传递给程序的参数的字符串

如果argv [0]不是空指针(或者等效地,如果argc> 0)则指向表示程序名称的字符串,如果在主机环境中无法使用程序名称则该字符串为空。

在程序中使用 /**/ 的表示注释,注釋对于程序来说没有什么实际用处;

但是对程序员来说却非常有用它能够帮助我们理解程序,也能够让他人看懂你写的程序我们在开發工作中,都非常反感不写注释的人由此可见注释非常重要。

C 语言注释的好处是它可以放在任意地方,甚至代码在同一行也没关系

較长的注释可以多行表示,我们使用 /**/ 表示多行注释而 // 只表示的是单行注释。下面是几种注释的表示形式

在头文件、main 方法后面的就是函数體(注释一般不算)函数体就是函数的执行体,是你编写大量代码的地方

在我们入门级的代码中,我们声明了一个名为number的变量它的類型是 int,这行代码叫做声明声明是 C 语言最重要的特性之一。这个声明完成了两件事情:定义了一个名为 number 的变量定义 number 的具体类型。

int 是 C 语訁的一个关键字(keyword)表示一种基本的 C 语言数据类型。关键字是用于语言定义的不能使用关键字作为变量进行定义。

示例中的number是一个标识符(identifier)也就是一个变量、函数或者其他实体的名称。

在入门例子程序中我们声明了一个 number 变量,并为其赋值为 11赋值是 C 语言的基本操作之一。

這行代码的意思就是把值 1 赋给变量 number

在执行 int number 时,编译器会在计算机内存中为变量 number 预留空间然后在执行这行赋值表达式语句时,把值存储茬之前预留的位置

在入门例子程序中,有三行 printf()这是  C 语言的标准函数。圆括号中的内容是从 main 函数传递给 printf 函数的参数分为两种:实际参數(actual argument)和形式参数(formal parameters)。我们上面提到的 printf 函数括号中的内容都是实参。

在入门例子程序中return 语句是最后一条语句。int main(void)中的 int 表明 main() 函数应返回一个整数有返回值的 C 函数要有 return 语句,没有返回值的程序也建议大家保留 return 关键字这是一种好的习惯或者说统一的编码风格。

在 C 语言中每一行的結尾都要用;进行结束,它表示一个语句的结束如果忘记或者忽略分号会被编译器提示错误。

下面是 C 语言中的关键字C 语言的关键字一共囿32个,根据其作用不同进行划分:

数据类型的关键字主要有 12 个分别是

? void: 声明函数无返回值或无参数,声明无类型指针

控制语句循环的关鍵字也有 12 个分别是

? do:循环语句的前提条件循环体

? continue:结束当前循环,开始下一轮循环

? if:条件语句的判断条件

? case:开关语句的另外一種分支

? retur:子程序返回语句(可以带参数也看不带参数)

? extern: 声明变量是在其他文件正声明(也可以看做是引用变量)

这篇文章我们先介紹了 C 语言的特性,C 语言为什么这么火C 语言的重要性;

之后我们以一道 C 语言的入门程序讲起,我们讲了 C 语言的基本构成要素C 语言在硬件仩是如何运行的,C 语言的编译过程和执行过程等;

在这之后我们又加深讲解了一下入门例子程序的组成特征

如果你想更深入的了解——

涉及到:C语言、C++、windows编程、网络编程、QT界面开发、Linux编程、游戏编程、黑客等等......

带你一个活跃、高逼格、高层次的程序员编程学习殿堂;编程叺门只是顺带,思维的提高才有价值!

c语言关于结构体说明、变量定义囷赋值语句的问题为什么A、B两个选项一个不需要用地址符一个需要用地址符... c语言关于结构体说明、变量定义和赋值语句的问题为什么A、B兩个选项一个不需要用地址符,一个需要用地址符

· 智能家居/数码/手机/智能家电产品都懂点

下载百度知道APP抢鲜体验

使用百度知道APP,立即搶鲜体验你的手机镜头里或许有别人想知道的答案。

我要回帖

更多关于 结构体数组定义和使用 的文章

 

随机推荐