TypeScript学习篇-类型介绍使用、ts相关面试题
文章目录
- 基础知识
- 基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)
- enum(枚举): 定义一个可枚举的对象
- type
- interface
- 联合类型: |
- 交叉类型: &
- any 类型
- null 和 undefined
- null
- undefined
- never类型
- 面试题及实战
- 1. 你觉得使用ts的好处是什么?
- 2. type 和 interface的异同
- 3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?
- 4. 什么是泛型, 泛型的具体使用?
- 5. 写一个计算时间的装饰器
- 6. 写一个缓存的装饰器
- 7. 实现一个路由跳转 通过ts约束参数的routeHelper
- 8. 实现一个基于ts和事件模式的countdown基础类
- 使用
- 9. npm install一个模块,都发生了什么
- 10. eventemitter3
执行ts文件命令:
tsc 文件.ts
基础知识
基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)
类型 | 关键字 | 描述 |
---|---|---|
任意类型 | any | 声明为 any 的变量可以赋予任意类型的值。 |
数字类型 | number | 双精度64位浮点值, 它可以用来表示整数和分数:let num: number = 666; |
字符串类型 | string | let str: string = '呀哈哈'; |
布尔类型 | boolean | let flag: boolean = true; |
数组类型 | 无 | 声明变量为数组 在元素类型后面加[]: let arr: number[] = [1,2]; , 或使用数组泛行: let arr:Array<number> = [1,2]; |
元组 | 无 | 元组类型用来表示已知元素数量和类型的数组, 各元素的类型不必相同, 对应位置的类型需要相同: let x:[string,number]; 正确: x = ['呀哈哈', 2]; 错误: x = [2, '呀哈哈']; |
枚举 | enum | 枚举类型用于定义数值集合 enum Color {Red, Green, Blue}; let c : Color = Color.Blue; console.log(c); // 2 |
void | void | 用于标识方法返回值的类型, 表示该方法没有返回值 function hello(): void{ alert('Hello World'); } |
null | null | 表示对象值缺失 |
undefined | undefined | 用于初始化变量为一个未定义的值 |
never | never | never是其他类型(包括 null 和 undefined) 的子类型, 代表从不会出现的值. |
enum(枚举): 定义一个可枚举的对象
const obj = {'RUN':'run','EAT':'eat'
}
enum Obj {'RUN',// 默认 RUN = 0'EAT', // 默认 EAT = 1'ABC' = 'abc', // 使用 '=' 复制
}
// 使用
const eat = Obj.EAT;const getValue = () => {return 0
}enum List {A = getValue(),B = 2, // 此处必须要初始化值,不然编译不通过C
}
console.log(List.A) // 0
console.log(List.B) // 2
console.log(List.C) // 3
type
type Action = 'eat' | 'run';
// 声明 a 变量类型为 Action, 可选值为:'eat', 'run'
const a:Action = 'eat';
interface
interface data {name: string,age: number
};
const b: data = {name: 'yhh',age: 10
}
// 定义axios.post 返回值类型
axios.post<data>().then();
联合类型: |
交叉类型: &
any 类型
任意值是 typescript 针对编程时类型不明确的变量使用的一种数据类型. 常用于以下三种情况
// 变量的值会动态改变时, 比如来着用户的输入, 任意值类型可以让这些变量跳过编译阶段的类型检查
let x: any = 1;
x = 'yhh';
x = false;// 改写现有代码时, 任意值允许在编译时可选择地包含或移除类型检查
let x: any = 4;
x.isEmpty(); // 正确, isEmpty方法在运行时可能存在, 但这里并不会检查
x.toFixed(); // 正确// 定义存储各种类型数据的数组时
ler arrayList: any[] = [1,false,'fine'];
arratList[1] = 100;
null 和 undefined
null
null
在 JavaScript
中 表示’什么都没有’.
null
是一个只有一个值的特殊类型, 表示一个空对象引用.
用 typeof
检测 null
返回是 object
.
undefined
undefined
在 javascript
中是一个没有设置值的变量.
typeof
一个没有值的变量会返回 undefined
.
Null
和 Undefined
是其他任何类型(包括void
)的子类型. 可以赋值给其他类型, 比如数字类型, 赋值后的类型会变成 null
或 undefined
.
在 typescript
中启用严格的空检验(--strictnullChecks
)特性, 就可以使 null
和 undefined
只能被赋值给 void
或本身对应的类型.
// 启用 --strictnullChecks
let x : number;
x = 1;
x = undefined; // 错误, 因为 x 只能是数字类型
x = null; // 错误// 如果一个类型可能出现 null 或 undefined, 可以使用 | 类支持多中类型
// 启用 --strictnullChecks
let x : number | null | undefined;
x = 1;
x = undefined; // 正确
x = null; // 正确
never类型
never
是其他类型(包括null
和undefined
)的子类型, 代表从不会出现的值. 这意味着声明never
类型的变量只能被never
类型所赋值, 在函数中通常表现为抛出异常或无法执行到终止点.
let x : never;
let y : number;x = 123; // 错误, 数字类型不可转为 never 类型// 正确, never 类型可以赋值给 never类型
x = (()=>{ throw new Error('exception') })();
// 正确, never 类型可以赋值给 数字类型
y = (()=>{ throw new Error('exception') })();// 返回值为 never 的函数可以是抛出异常的情况
function error(message:string): never{throw new Error(message);
}
// 返回值为 never 的函数可以是无法被执行到终止点的情况
function loop(): never{while (true){}
}
面试题及实战
1. 你觉得使用ts的好处是什么?
1.1 TypeScript是JavaScript的加强版,它给JavaScript添加了可选的静态类型和基于类的面向对象编程,它拓展了JavaScript的语法。所以ts的功能比js只多不少.
1.2 Typescript 是纯面向对象的编程语言,包含类和接口的概念.
1.3 TS 在开发时就能给出编译错误, 而 JS 错误则需要在运行时才能暴露。
1.4 作为强类型语言,你可以明确知道数据的类型。代码可读性极强,几乎每个人都能理解。
1.5 ts中有很多很方便的特性, 比如可选链.
2. type 和 interface的异同
重点:用interface描述数据结构,用type描述类型
2.1 都可以描述一个对象或者函数
interface User {name: stringage: number
}interface SetUser {(name: string, age: number): void;
}type User = {name: stringage: number
};type SetUser = (name: string, age: number)=> void;
2.2 都允许拓展(extends)
interface 和 type 都可以拓展,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 extends interface 。 虽然效果差不多,但是两者语法不同。
// interface extends interface
interface Name { name: string;
}
interface User extends Name { age: number;
}// type extends type
type Name = { name: string;
}
type User = Name & { age: number };// interface extends type
type Name = { name: string;
}
interface User extends Name { age: number;
}// type extends interface
interface Name { name: string;
}
type User = Name & { age: number;
}
2.3 只有type可以做的
type 可以声明基本类型别名,联合类型,元组等类型
// 基本类型别名
type Name = string// 联合类型
interface Dog {wong();
}
interface Cat {miao();
}type Pet = Dog | Cat// 具体定义数组每个位置的类型
type PetList = [Dog, Pet]// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div
3. 如何基于一个已有类型, 扩展出一个大部分内容相似, 但是有部分区别的类型?
首先可以通过Pick和Omit
interface Test {name: string;sex: number;height: string;
}type Sex = Pick<Test, 'sex'>;const a: Sex = { sex: 1 };type WithoutSex = Omit<Test, 'sex'>;const b: WithoutSex = { name: '1111', height: 'sss' };
比如Partial, Required.
再者可以通过泛型.
4. 什么是泛型, 泛型的具体使用?
泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。
可以把泛型理解为代表类型的参数
interface Test<T = any> {userId: T;
}type TestA = Test<string>;
type TestB = Test<number>;const a: TestA = {userId: '111',
};const b: TestB = {userId: 2222,
};
5. 写一个计算时间的装饰器
export function before(beforeFn: any) {return function(target: any, name: any, descriptor: any) {const oldValue = descriptor.value;descriptor.value = function() {beforeFn.apply(this, arguments);return oldValue.apply(this, arguments);};return descriptor;};
}export function after(afterFn: any) {return function(target: any, name: any, descriptor: any) {const oldValue = descriptor.value;descriptor.value = function() {const ret = oldValue.apply(this, arguments);afterFn.apply(this, arguments);return ret;};return descriptor;};
}
// 计算时间
export function measure(target: any, name: any, descriptor: any) {const oldValue = descriptor.value;descriptor.value = async function() {const start = Date.now();const ret = await oldValue.apply(this, arguments);console.log(`${name}执行耗时 ${Date.now() - start}ms`);return ret;};return descriptor;
}
6. 写一个缓存的装饰器
const cacheMap = new Map();export function EnableCache(target: any, name: string, descriptor: PropertyDescriptor) {const val = descriptor.value;descriptor.value = async function(...args: any) {const cacheKey = name + JSON.stringify(args);if (!cacheMap.get(cacheKey)) {const cacheValue = Promise.resolve(val.apply(this, args)).catch((_) => cacheMap.set(cacheKey, null));cacheMap.set(cacheKey, cacheValue);}return cacheMap.get(cacheKey);};return descriptor;
}
7. 实现一个路由跳转 通过ts约束参数的routeHelper
import { Dictionary } from 'vue-router/types/router';
import Router, { RoutePath } from '../router';export type BaseRouteType = Dictionary<string>;export interface IndexParam extends BaseRouteType {name: string;
}export interface AboutPageParam extends BaseRouteType {testName: string;
}export interface UserPageParam extends BaseRouteType {userId: string;
}export interface ParamsMap {[RoutePath.Index]: IndexParam;[RoutePath.About]: AboutPageParam;[RoutePath.User]: UserPageParam;
}export class RouterHelper {public static replace<T extends RoutePath>(routePath: T, params: ParamsMap[T]) {Router.replace({path: routePath,query: params,});}public static push<T extends RoutePath>(routePath: T, params: ParamsMap[T]) {Router.push({path: routePath,query: params,});}
}
8. 实现一个基于ts和事件模式的countdown基础类
import { EventEmitter } from 'eventemitter3';export interface RemainTimeData {/** 天数 */days: number;/*** 小时数*/hours: number;/*** 分钟数*/minutes: number;/*** 秒数*/seconds: number;/*** 毫秒数*/count: number;
}export type CountdownCallback = (remainTimeData: RemainTimeData, remainTime: number) => void;enum CountdownStatus {running,paused,stoped,
}
// 练习
interface User {name: stringage: number
}
function test<T extends User>(params: T): T{return params
}
test({name:'1',age:1});export enum CountdownEventName {START = 'start',STOP = 'stop',RUNNING = 'running',
}
interface CountdownEventMap {[CountdownEventName.START]: [];[CountdownEventName.STOP]: [];[CountdownEventName.RUNNING]: [RemainTimeData, number];
}export function fillZero(num: number) {return `0${num}`.slice(-2);
}export class Countdown extends EventEmitter<CountdownEventMap> {private static COUNT_IN_MILLISECOND: number = 1 * 100;private static SECOND_IN_MILLISECOND: number = 10 * Countdown.COUNT_IN_MILLISECOND;private static MINUTE_IN_MILLISECOND: number = 60 * Countdown.SECOND_IN_MILLISECOND;private static HOUR_IN_MILLISECOND: number = 60 * Countdown.MINUTE_IN_MILLISECOND;private static DAY_IN_MILLISECOND: number = 24 * Countdown.HOUR_IN_MILLISECOND;private endTime: number;private remainTime: number = 0;private status: CountdownStatus = CountdownStatus.stoped;private step: number;constructor(endTime: number, step: number = 1e3) {super();this.endTime = endTime;this.step = step;this.start();}public start() {this.emit(CountdownEventName.START);this.status = CountdownStatus.running;this.countdown();}public stop() {this.emit(CountdownEventName.STOP);this.status = CountdownStatus.stoped;}private countdown() {if (this.status !== CountdownStatus.running) {return;}this.remainTime = Math.max(this.endTime - Date.now(), 0);this.emit(CountdownEventName.RUNNING, this.parseRemainTime(this.remainTime), this.remainTime);if (this.remainTime > 0) {setTimeout(() => this.countdown(), this.step);} else {this.stop();}}private parseRemainTime(remainTime: number): RemainTimeData {let time = remainTime;const days = Math.floor(time / Countdown.DAY_IN_MILLISECOND);time = time % Countdown.DAY_IN_MILLISECOND;const hours = Math.floor(time / Countdown.HOUR_IN_MILLISECOND);time = time % Countdown.HOUR_IN_MILLISECOND;const minutes = Math.floor(time / Countdown.MINUTE_IN_MILLISECOND);time = time % Countdown.MINUTE_IN_MILLISECOND;const seconds = Math.floor(time / Countdown.SECOND_IN_MILLISECOND);time = time % Countdown.SECOND_IN_MILLISECOND;const count = Math.floor(time / Countdown.COUNT_IN_MILLISECOND);return {days,hours,minutes,seconds,count,};}
}
使用
<template><div class="home" @click="toAboutPage"><img alt="Vue logo" src="../assets/logo.png"><HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/><div>倒计时:{{timeDisplay}}</div></div>
</template><script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from '../components/HelloWorld.vue';
import { RouterHelper } from '../lib/routerHelper';
import { Countdown, CountdownEventName, fillZero } from '../lib/countdown';
import { RoutePath } from '../router';
import { measure } from '../decorator';@Component({components: {HelloWorld,},
})
export default class Home extends Vue {public timeDisplay: string = '';@measurepublic toAboutPage() {RouterHelper.push(RoutePath.About, { testName: '1111' });}public created() {const countdown = new Countdown(Date.now() + 60 * 60 * 1000, 10);countdown.on(CountdownEventName.RUNNING, (remainTimeData) => {const { hours, minutes, seconds, count} = remainTimeData;this.timeDisplay = [hours, minutes, seconds, count].map(fillZero).join(':');});}
}
</script>
9. npm install一个模块,都发生了什么
npm install命令输入 > 检查node_modules目录下是否存在指定的依赖 > 如果已经存在则不必重新安装 > 若不存在,继续下面的步骤 > 向 registry(本地电脑的.npmrc文件里有对应的配置地址)查询模块压缩包的网址 > 下载压缩包,存放到根目录里的.npm目录里 > 解压压缩包到当前项目的node_modules目录中。
10. eventemitter3
相关文章:

TypeScript学习篇-类型介绍使用、ts相关面试题
文章目录 基础知识基础类型: number, string, boolean, object, array, undefined, void(代表该函数没有返回值)enum(枚举): 定义一个可枚举的对象typeinterface联合类型: |交叉类型: &any 类型null 和 undefinednullundefined never类型 面试题及实战1. 你觉得使用ts的好处…...

超详细!Jmeter性能测试
前言 性能测试是一个全栈工程师/架构师必会的技能之一,只有学会性能测试,才能根据得到的测试报告进行分析,找到系统性能的瓶颈所在,而这也是优化架构设计中重要的依据。 测试流程: 需求分析→环境搭建→测试计划→脚…...

C语言经典习题24
文件操作习题 一 编程删除从C盘home文件夹下data.txt文本文件中所读取字符串中指定的字符,该指定字符由键盘输入,并将修改后的字符串以追加方式写入到文本文件C:\home\data.txt中。 #include<stdio.h> main() { char s[100],ch; int i;…...

SQL labs-SQL注入(三,sqlmap使用)
本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 引言: 盲注简述:是在没有回显得情况下采用的注入方式,分为布尔盲注和时间盲注。 布尔盲注:布尔仅有两种形式,ture&#…...

统一认证与单点登录:简明概述与应用
1. 统一认证概述 统一认证是一种身份验证机制,允许用户使用一个账户来访问多个系统和应用程序。它的主要目标是简化用户的登录过程,提高安全性,并减少管理开销。统一认证通过集中管理用户信息,使得用户只需一次认证即可访问不同的…...

MSPM0G3507学习笔记1:开发环境_引脚认识与点灯
今日速通一款Ti的单片机用于电赛:MSPM0G3507 这里默认已经安装好了Keil5_MDK 首先声明一下: 因为是速成,所以需要一定单片机学习基础,然后我写的也不会详细,这个专栏的笔记也就是自己能看懂就行的目标~~~ 文章提供测试代码解…...

使用法国云手机进行面向法国的社媒营销
在当今数字化和全球化的时代,社交媒体已经成为企业营销和拓展市场的重要工具。对于想进入法国市场的企业来说,如何在海外社媒营销中脱颖而出、抓住更多的市场份额,成为了一个关键问题。法国云手机正为企业提供全新的营销工具,助力…...

C++学习笔记——模板
学习视频 文章目录 模板的概念函数模板函数模板语法函数模板注意事项函数模板案例普通函数与函数模板的区别普通函数与函数模板的调用规则模板的局限性 类模板类模板与函数模板区别类模板中成员函数创建时机类模板对象做函数参数类模板与继承类模板成员函数类外实现类模板分文件…...

财务分析,奥威BI行计算助力财务解放报表工作
【财务分析,奥威BI行计算助力财务解放报表工作】 在企业的财务管理体系中,财务报表的编制与分析是至关重要的一环。然而,传统的手工编制报表方式不仅耗时耗力,还难以应对日益复杂多变的财务数据需求。奥威BI(Business…...

文件写入、读出-linux
基于linux操作系统,编写存储功能,在网上搜了几个例子,一直报创建错误, fopen(SAVE_PATH_OWN_INF_FILE, "w") fopen(SAVE_PATH_OWN_INF_FILE, "a"), 使用这两个创建均失败,最后发现创建可以用以…...

环境搭建-Windows系统搭建Docker
Windows系统搭建Docker 一、系统虚拟化1.1 启用虚拟化2.2 启用Hyper-v并开启虚拟任务 三、安装WSL3.1 检验安装3.2 安装WSL 四、Docker安装4.1 Docker安装包下载4.2 Docker安装4.3 运行docker Desktop 五、Docker配置5.1 打开Docker配置中心5.2 配置Docker国内镜像 六、使用 一…...

k8s零零散散问题
安装教程 https://blog.csdn.net/weixin_43933728/article/details/137977799 加入集群错误问题 https://blog.csdn.net/Linbling/article/details/139122862...

The Llama 3 Herd of Models.Llama 3 模型论文全文
现代人工智能(AI)系统是由基础模型驱动的。本文提出了一套新的基础模型,称为Llama 3。它是一组语言模型,支持多语言、编码、推理和工具使用。我们最大的模型是一个密集的Transformer,具有405B个参数和多达128K个tokens的上下文窗口。本文对Llama 3进行了广泛的实证评价。我们…...

ChatGPT的原理和成本
ChatGPT就是人机交互的一个底层系统,某种程度上可以类比于操作系统。在这个操作系统上,人与AI之间的交互用的是人的语言,不再是冷冰冰的机器语言,或者高级机器语言,当然,在未来的十来年内,机器语…...

无刷电机的ESC电子速度控制模块夹紧铁芯或更换镇流器
△u/s中后一项经过二极管半波整流、电容C1滤波后,使原有的脉动电压曲线Us上再0.45ys的波形如叠加一个直流电压,其大小为-Lu,即为△U当压差△U太大,使0.45△U≥Ucz时,电容C1两端电压uc不可能降至下信号。所以该电路同样可以检测出压差压差较小时才能发出合闸脉冲。 压差△U的检…...

OpenAI发布AI搜索惨遭翻车?新老搜索的较量愈演愈烈!
引言 在信息爆炸的时代,每一次技术的飞跃都如同海平面上跃起的鲸鱼,既震撼人心,也搅动着深海的宁静。近日,科技巨头OpenAI发布的AI搜索功能,本欲以智能之名重塑搜索领域的版图,却不料遭遇了市场的“暗礁”…...

SpringBoot整合阿里云短信业务
详细介绍SpringBoot整合阿里云短信服务的每一步过程,同时会将验证码存放到Redis中并设置过期时间,尽量保证实战的同时也让没做过的好兄弟也能实现发短信的功能~ 1. 注册阿里云账号和创建Access Key 首先,你需要注册一个阿里云账号࿰…...

Kubernetes安全--securityContext介绍
作者:雅泽 securityContext是用来控制容器内的用户权限,你想用什么用户去执行程序或者执行操作等等。 1. securityContext介绍 安全上下文(Security Context)定义 Pod 或 Container 的特权与访问控制设置。 安全上下文包括但不…...

【React】通过实际示例详解评论列表渲染和删除
文章目录 一、引言二、初始状态与状态更新1. 使用useState钩子管理状态2. 评论列表的初始数据 三、列表渲染的实现1. list.map(item > { ... })2. return 语句3. JSX 语法4. 为什么这样设计5. 完整解读 四、列表项的唯一标识1. key 的作用2. key 的用法3. 可以没有 key 吗&a…...

React 中 useState 语法详解
1. 语法定义 const [state, dispatch] useState(initData) state:定义的数据源,可视作一个函数组件内部的变量,但只在首次渲染被创造。 dispatch:改变state的函数,推动函数渲染的渲染函数,有非函数和函…...

(面试必看!)一些和多线程相关的面试考点
文章导读 引言考点1. CAS 指令(重点)一、什么是CAS二、CAS 的优点三、CAS 的缺点四、ABA问题五、相关面试题 考点2. 信号量(semaphore)一、基本概念二、信号量的主要操作三、信号量的应用四、相关面试题 考点3、CountDownLatch 类…...

从零到一使用 Ollama、Dify 和 Docker 构建 Llama 3.1 模型服务
本篇文章聊聊,如何使用 Ollama、Dify 和 Docker 来完成本地 Llama 3.1 模型服务的搭建。 如果你需要将 Ollama 官方不支持的模型运行起来,或者将新版本 llama.cpp 转换的模型运行起来,并且想更轻松的使用 Dify 构建 AI 应用,那么…...

【React】详解 React Router
文章目录 一、React Router 的基本概念1. 什么是 React Router?2. React Router 的主要特性 二、React Router 的核心组件1. BrowserRouter2. Route3. Link4. Switch 三、React Router 的使用方法1. 安装 React Router2. 定义路由组件3. 配置路由4. 启动应用 四、Re…...

微软蓝屏”事件暴露了网络安全哪些问题?
📢博客主页:https://blog.csdn.net/2301_779549673 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 JohnKi 原创,首发于 CSDN🙉 📢未来很长&#…...

upload-labs靶场练习
文件上传函数的常见函数: 在PHP中,文件上传涉及的主要函数包括move_uploaded_file(), is_uploaded_file(), get_file_extension(), 和 mkdir()。这些函数共同协作,使得用户可以通过HTTP POST方法上传文件,并在服务器上保存…...

java使用hutool工具判断ip或者域名是否可用,java使用ping判断ip或者域名是否可用
1.导入hutool工具 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency>2.复制以下代码直接运行 import cn.hutool.core.net.NetUtil;public class Test {p…...

apache2和httpd web服务器
apache2和httpd web服务器 apache2和httpd web服务器是啥apache是软件基金会apache2是一个web服务httpd和apache2是同一个东西,但是不同linux发行版中叫法不一样。就是同一个东西,但是看上去有一些不一样。 apache2和httpd web服务器是啥 apache是软件基…...

基于多种机器学习的豆瓣电影评分预测与多维度可视化【可加系统】
有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 在本研究中,我们采用Python编程语言,利用爬虫技术实时获取豆瓣电影最新数据。通过分析豆瓣网站的结构,我们设计了一套有效的策略来爬取电影相关的JSON格式数据。…...

Linux系统配置STM32的开发环境(代码编辑,编译,下载调试)
常见的stm32开发都是直接使用keil-MDK工具的,这是个集成开发环境,包含了代码编辑,编译,下载,调试,等功能,而且keil还是个图形化操作工具,直接可以点击图标案件就可以实现编译下载啥的…...

每日一题——第三十五题
题目:有一个文本文件numbers.txt,其中有20个整数,每个整数占一行,编写程序将这些整数从小到大顺序排好后,重新写入到该文件中, 要求排序前和排序后都要输出该文件的内容。 #include<stdio.h> #inclu…...