C语言学习(十七)---结构体(2)、外部变量声明

在之前的内容中,我们学习了强制类型转换条件操作符以及逗号表达式,今天我们将继续往下学习,学习的主要内容有结构体(2),以及对外部变量进行仿真。好了,话不多说,开整!!!

结构体(2)

在前面的内容中,我们已经对结构体进行了一定的介绍,并介绍了其最基本的定义和使用方法,大家不知道或者忘记的可以自行查看,链接如下:初始结构体,今天我们继续对其进行较为深入的学习。

多个结构体定义

结构体除了基本的定义方式外,其另一种定义方式如下所示:

struct Radar
    {
    int fc;
    double B;
    double Tp;
    char type[20];
    } radar1,radar2;

其中的radar1radar2即是想要定义的结构体的名字,这样就可以同时创建两个内容相同的结构体,那么此处定义的结构体和以前讲述的定义的结构体的方式有什么区别呢?区别就在于:

此处的定义的结构体为全局变量,之前创建的结构体为局部变量

重命名结构体的类

什么是结构体的呢?如上述所示的代码,我们所创建的结构体类Radar,那此时我们想要给此结构体赋值就需要使用以下代码:

struct Radar radar = {******};

未免有些过长,因此我们可以重命名结构体的类,然后再对结构体赋值,如下述所示代码:

 typedef   struct Radar
    {
    int fc;
    double B;
    double Tp;
    char type[20];
    } Radar;

此时我们把结构体的类重新定义为Radar,此时再对结构体初始化时就只需以下代码:

Radar radar1 = {50,20.5,22.336,"phase_ayy"};

看起来是不是比上面的简洁一些,测试代码如下:

#include<stdio.h>
typedef   struct Radar
    {
    int fc;
    double B;
    double Tp;
    char type[20];
    } Radar;  
int main()
{

    Radar radar1 = {50,20.5,22.336,"phase_ayy"};
    printf("%d\n",radar1.fc);
    return 0;
}

保存编译运行,得到以下结果:

在这里插入图片描述

结构体的第二种访问方式

前面的内容中,我们对于结构体中的内容都是“.”方式即普通变量访问的方式进行数据读取的,那么既然结构体为一种变量类型,其是不是也可以通过指针进行访问呢?又如何进行访问呢?下面进行验证。
既然仍以上述代码为例,我们定义了一个类型为Radar的结构体,那么其对应的指针类型则应该为:

Radar* p = &rada1;

如果你存在疑惑,请回看该文章:基础学习3中指针变量的相关内容,此时我们 定义了一个指针变量p,那么能否通过指针访问结构体呢?示例代码如下:

#include<stdio.h>
typedef   struct Radar
    {
    int fc;
    double B;
    double Tp;
    char type[20];
    } Radar;  
void print(Radar radar1)
{
    printf("%s\n",radar1.type);
}
int main()
{

    Radar radar1 = {50,20.5,22.336,"phase_ayy"};
    Radar* p = &radar1;
    printf("%s\n",p.type);
    return 0;
}

编译运行,报错了:在这里插入图片描述
提示我们p是一个指针,你是不是想用->,那么我们改成这个,再进行编译,发现编译成功:
在这里插入图片描述
由此,我们可知:

结构体可以通过指针进行访问
指针的访问方式为->

结构体传参方式选择

结构体,作为多个不同变量的集合,当然也可以在函数中进行传递,那么我们在实参与形参这一节中,介绍了传递参数的两种方式,可以选择传值,也可以选择传址,那么结构体是传值好呢还是传址好呢,我们来进行说明。
如以下代码:

#include<stdio.h>
typedef   struct Radar
    {
    int fc;
    double B;
    double Tp;
    char type[20];
    } Radar;  
void print(Radar radar1) //传过来为结构体的值,所以接收为结构体的值
{
    printf("%s\n",radar1.type);
}
void print2(Radar* radar1)//传过来为结构体的地址,所以接收为指针变量
{
    printf("%s\n",radar1->type);//结构体指针采用->方式访问
}
int main()
{

    Radar radar1 = {50,20.5,22.336,"phase_ayy"};
    print(radar1);
    print2(&radar1);
    return 0;
}

如上所示,我们定义了一个结构体,其中存放了一些值,然后自定义了两个函数用来打印结构体中的字符串。
两个自定义函数的之间的区别就在与传入的内容不同print函数传递的是print2传递的是地址,那么这两种方式哪种好呢?在讲解之前,我们先看一下运行结果:
在这里插入图片描述
可以看到运行结果是一样的,那这有什么好坏之分呢?
当然有区别了,因为我们在之前的内容讲过,传值的时候相当于是在内存中重新开辟了一段空间来存储所传递的值,然会自定义函数内部运算结束后,再销毁,因此,如果结构体的内容过于丰富,就会在内存中占用大量的临时资源,这是我们不想看到的,而传址操作就不会开辟新的空间,而是通过内存中的地址,直接访问结构体中的对应内容,所以建议:

结构体传址操作更好
既然传址,则需要使用->访问结构体中的内容

外部变量(补)

C语言学习(四)这一节的学习内容中,我们学习了外部变量的使用,但是由于我的编译配置问题,并未对其进行编译测试,今天我在此处,对那一节的内容进行编译测试,详细内容请见上述链接:

编译修复

为什么在引用外部变量时会报错,其中的一个主要原因就是编译器的链接问题,我是在参考了这两篇文章之后,对其进行了一个地方的修改,修改之后就可以使用外部变量了,参考文章如下:
参考文章1
参考文章2
简单来说按如下方式进行操作:
在这里插入图片描述
进入该文件后将"${file}",替换为:

"${fileDirname}\\*.c",//替换后的

在这里插入图片描述
至此,连接问题就解决了。

演示

我们首先定义一个外部的头文件,命名为extern.h,然后在其内部定义两个变量如下:

int g_val = 2023;
double v_val = 3.1415926;

然后在测试文件中引入头文件,并打印两个变量,代码如下:

#include<stdio.h>
#include"extern.h"
extern int g_val;
extern double v_val;
int main()
{

    printf("g_val = %d\n v_val = %lf\n",g_val,v_val);
    return  0;
}

编译查看结果如下:
在这里插入图片描述
以上就是外部变量在其他函数中使用的方式了。

上述内容即使今天的全部内容了,感谢大家的观看。
如果方便,辛苦大家点个赞和关注哦!
您的点赞或评论或关注是对我最大的肯定,谢谢大家!!!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
c语⾔程序⽂件的写法,C语⾔-⽂件 所谓"⽂件"是指⼀组相关数据的有序集合,该数据的集合的名字就是⽂件名。⽂件可以分为很多类,如源程序⽂件、⽬标⽂件、可执⾏⽂ 件、库⽂件等等。 ⽂件通常是存放在外部介质上的(例如磁盘等),在使⽤时才会被调⼊内存中并执⾏。从⽤户的⾓度来看⽂件可以分为普通⽂件和设备⽂件。 普通⽂件是指存放在磁盘或者其它外部介质上的⼀个有序的集合,可以是源⽂件、⽬标⽂件、可执⾏程序等;也可以是⼀组待输⼊处理的原 始数据,或是⼀组输出的结果。对于源⽂件、⽬标⽂件、可执⾏程序可以称作程序⽂件,⽽输⼊输出数据可以称作数据⽂件。 设备⽂件是指与主机相联的各种外部设备,如显⽰器、打印机、键盘等。在操作系统中,把外部设备也看作是⼀个⽂件来进⾏管理,把他们 的输⼊输出等同于对磁盘⽂件的读写。 从⽂件编码的形式来看,⽂件可以分为ASCII码⽂件和⼆进制码⽂件。ASCII码⽂件也称作为⽂本⽂件,这种⽂件在磁盘中存放时每个字符 对应⼀个字节,⽤于存放相应的ASCII码。 ⼆进制⽂件是以⼆进制编码的⽅式来编写⽂件的。⼆进制⽂件虽然可以显⽰在屏幕上,但是却不能读懂。 ⽂件的指针 在C语⾔中⽤⼀个指针变量指向⼀个⽂件,那么这个指针称为⽂件指针。另外,我们通过⽂件指针就可以对所指的⽂件进⾏各种操作。 ⼀般形式为: FILE* ⽂件变量标识符 解释:FILE应该是⼤写的,它实际上是由系统定义的⼀个结构体,该结构体包含了⽂件名、⽂件状态和⽂件当前位置等信息,因此在编写程 序的时候我们不需要过于关⼼FILE结构的细节部分。 // 案例1: FILE *fp; /*说明: fp表⽰FILE结构的指针变量,通过fp可以找到存放某⼀个⽂件信息的结构变量, 然后按照结构体提供的信息找到该⽂件,并对⽂件进⾏操作。*/ ⽂件的打开和关闭 ⽂件在进⾏读写操作之前,要打开⽂件,当使⽤完后应关闭⽂件。打开⽂件就是建⽴⽂件的各种有关信息,并使⽂件指针指向⽂件,以便进 ⾏其他操作。⽽关闭⽂件就是切断⽂件指针和⽂件之间的关系,换⽽⾔之,就是禁⽌利⽤指针操作⽂件。 在C语⾔中,⽂件操作都是由库函数完成的。如fopen 和 fclose。 1. ⽂件的打开 fopen() fopen() 函数是⽤来打开⼀个⽂件,其⼀般的调⽤形式为: ⽂件指针名 = fopen(⽂件名,使⽤⽂件的⽅式); 注释: ⽂件指针名:必须被说明为FILE类型的指针变量; ⽂件名:被打开⽂件的⽂件名; 使⽤⽂件的⽅式:⽂件的类型和操作要求 // 案例2: FILE* fp; fp = fopen("text","r"); /*说明: 在当前⽬录下打开⽂件text,只允许"读"的操作,并且让fp指针指向该⽂件*/ 使⽤⽂件的⽅式有12种,如下所⽰: "使⽤⽂件⽅ " 意义 " "----------"------------------------------:" ""rt" " 只读打开⼀个⽂本,只允许读" ""wt" " 只写打开或者建⽴⼀个⽂件,只允许写数据" ""at" " 追加打开⼀个⽂件,并在⽂件末尾写数据" ""rb" " 只读打开⼀个⼆进制⽂件,只允许读" ""wt" " 只写打开或者建⽴⼀个⽽进制⽂件,只允许写" ""ab" " 追加打开⼀个⼆进制⽂件,并在⽂件末尾写数据" ""rt+" " 读写打开⼀个⽂件,允许读和写 " " "wt+" " 读写打开或建⽴⼀个⽂件,允许读写" ""at+" " 读写打开⼀个⽂件,允许读,或在⽂件末尾追加数据" ""rb+" " 读写打开⼀个⼆进制⽂件,允许读写" ""wb+" " 读写打开或者建⽴⼀个⼆进制⽂件,允许读写 " ""ab+" " 读写打开⼀个⼆进制⽂件,允许读,或在⽂件末追加数据" 说明: 由r、w、a、t、b、+六个字符拼成,个字符的意义: r(read):读 w(write):写 a(append):追加 t(text):⽂本⽂件,可省略不写 b(banary):⼆进制⽂件 6.+:读和写 // 案例3: FILE* fp; fd = fopen("./text","r"); if (NULL == fd) { printf("open error\n"); exit(1); } // ⽤读"r"的⽅式打开⽂件"./text";若⽂件打开失败时,fp为空,输出open error。 2. ⽂件的关闭 fclose()函数是指当⽂件使⽤完后,需要关闭⽂件。其⼀般形式为: fclose(⽂件指针); // 案例4: fclose(fp); // 说明:正常关闭⽂件时,fclose()函数的返回值是0。若返回⼀个⾮零的值,则表⽰关闭⽂件时发⽣错误 ⽂件的读写 ⽂件的读写是有多重⽅式的,它可以⼀个字节⼀个字节的读或写,也可以是⼀串⼀串的读或
简介: C语言是编程语言中的一朵奇葩,虽已垂垂老矣,但却屹立不倒,诞生了数十年,仍然是最流行的编程语言之一。C语言看似简单,却不易吃透,想要运用好,更是需要积淀。本书是一本修炼C程序设计能力的进阶之作,它没有系统地去讲解C语言的语法和编程方法,而是只对C语言中不容易被初学者理解的重点、难点和疑点进行了细致而深入的解读,揭露了C语言中那些鲜为普通开发者所知的秘密,旨在让读者真正掌握C语言,从而编写出更高质量的C程序代码。 全书一共11章:第1章重点阐述了C语言中不易被理解的多个核心概念,很多初学者在理解这些概念时都会存在误区;第2~8章对预处理、选择结构和循环结构的程序设计、数组、指针、数据结构、函数和文件等知识点的核心问题和注意事项进行了讲解;第9章介绍了调试和异常处理的方法及注意事项;第10章对C语言中的若干容易让开发者误解误用的陷阱知识点进行了剖析;第11章则对所有程序员必须掌握的几种算法进行了详细的讲解;附录经验性地总结了如何养成良好的编码习惯,这对所有开发者都尤为重要。 本书主要内容:  堆和栈、全局变量和局部变量、生存期和作用域、内部函数和外部函数、指针变量、指针数组和数组指针、指针函数和函数指针、传址和传值、递归和嵌套、结构体和共用体、枚举、位域等较难理解的核心概念的阐述和对比;  预处理中的疑难知识点,包括文件的包含方式、宏定义及其常见错误解析、条件编译指令和#pragma指令的使用等;  if、switch等选择结构语句的使用注意事项和易错点解析;  for、while、do while等循环结构语句的使用注意事项和易错点解析;  循环结构中break、continue、goto、return、exit的区别;  一维数组、二维数组、多维数组、字符数组、动态数组的定义和引用,以及操作数组时的各种常见错误解析;  不同类型的指针之间的区别,以及指针的一般用法和注意事项;  指针与地址、数组、字符串、函数之间的关系,以及指针与指针之间的关系;  枚举类型的使用及注意事项,结构体变量和共用体变量的初始化方法及引用;  传统链表的实现方法和注意事项,以及对传统链表实现方法的颠覆;  与函数参数、变参函数、函数调用、函数指针相关的一些难理解和容易被理解错的知识点解析;  文件和指针的使用原则、技巧和注意事项;  函数调用和异常处理的注意事项和最佳实践;  与strlen、sizeof、const、volatile、void、void*、#define、typedef、realloc、malloc、calloc等相关的一些陷阱知识点的解析;  时间复杂度、冒泡排序法、选择排序法、快速排序法、归并排序法、顺序排序法、二分查找等常用算法的详细讲解;  良好的编码习惯和编程风格。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器 xiaohu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值