运算符
C 语言的运算符非常多,一共有 50 多种,可以分成若干类。
算术运算符
算术运算符专门用于算术运算,主要有下面几种。
+:正值运算符(一元运算符)
-:负值运算符(一元运算符)
+:加法运算符(二元运算符)
-:减法运算符(二元运算符)
*:乘法运算符
/:除法运算符
%:余值运算符
(1)+,-
+和-既可以作为一元运算符,也可以作为二元运算符。所谓“一元运算符”,指的是只需要一个运算数就可以执行。一元运算符-用来改变一个值的正负号。
1int x = -12;
上面示例中,-将12这个值变成-12。
一元运算符+对正负值没有影响,是一个完全可以省略的运算符,但是写了也不会报错。
12int x = -12;int y = +x;
上面示例中,变量y的值还是-12,因为+不会改变正负值。
二元运算符+和-用来完成加法和减法。
12int x = 4 + 22;int y = 61 - 23;
(2)*
运算符*用来完成乘法。
12int num = 5;printf("%i\n", num * num); // 输出 25
(3)/
运算符/ ...
变量
变量(variable)可以理解成一块内存区域的名字。通过变量名,可以引用这块内存区域,获取里面存储的值。由于值可能发生变化,所以称为变量,否则就是常量了。
变量名
变量名在 C 语言里面属于标识符(identifier),命名有严格的规范。
只能由字母(包括大写和小写)、数字和下划线(_)组成。
不能以数字开头。
长度不能超过63个字符。
下面是一些无效变量名的例子。
123456$zjj**p2catHot-tabtax ratedon't
上面示例中,每一行的变量名都是无效的。
变量名区分大小写,star、Star、STAR都是不同的变量。
并非所有的词都能用作变量名,有些词在 C
语言里面有特殊含义(比如int),另一些词是命令(比如continue),它们都称为关键字,不能用作变量名。另外,C
语言还保留了一些词,供未来使用,这些保留字也不能用作变量名。下面就是 C
语言主要的关键字和保留字。
auto, break, case, char, const, continue, default, do, double, else,
enum, exter ...
C 语言基本语法
语句
C
语言的代码由一行行语句(statement)组成。语句就是程序执行的一个操作命令。C
语言规定,语句必须使用分号结尾,除非有明确规定可以不写分号。
1int x = 1;
上面就是一个变量声明语句,声明整数变量x,并且将值设为1。
多个语句可以写在一行。
1int x; x = 1;
上面示例是两个语句写在一行。所以,语句之间的换行符并不是必需的,只是为了方便阅读代码。
一个语句也可以写成多行,这时就要依靠分号判断语句在哪一行结束。
12345int x;x=1;
上面示例中,第二个语句x = 1;被拆成了四行。编译器会自动忽略代码里面的换行。
单个分号也是有效语句,称为“空语句”,虽然毫无作用。
1;
表达式
C
语言的各种计算,主要通过表达式完成。表达式(expression)是一个计算式,用来获取值。
11 + 2
上面代码就是一个表达式,用来获取1 + 2这个算术计算的结果。
表达式加上分号,也可以成为语句,但是没有实际的作用。
128;3 + 4;
上面示例是两个表达式,加上分号以后成为语句。
表达式与语句的区别主要是两点:
语句可以 ...
编译选项
TypeScript
提供了非常多的编译选项,但是官方文档对每一项的解释很抽象,这一章会详细介绍每一个选项的作用,并给出对应的示例。
索引(点击选项跳转到详细介绍):
选项
类型
默认值
描述
allowJs
boolean
false
允许编译 js 文件
allowSyntheticDefaultImports
boolean
false
允许对不包含默认导出的模块使用默认导入。这个选项不会影响生成的代码,只会影响类型检查。
allowJs
允许编译 js 文件。
设置为 true 时,js 文件会被 tsc
编译,否则不会。一般在项目中 js, ts 混合开发时需要设置。
查看示例
123456789101112131415161718# 设置为 true 时,编译后的文件包含 foo.js├── lib│ ├── foo.js│ └── index.js├── src│ ├── foo.js│ └── index.ts├── package.json└── tsconfig.json``````# 设置为 false 时,编译后的文件不包含 foo ...
代码检查
2019 年 1 月,TypeScirpt
官方决定全面采用 ESLint 作为代码检查的工具,并创建了一个新项目 typescript-eslint,提供了
TypeScript 文件的解析器 @typescript-eslint/parser
和相关的配置选项 @typescript-eslint/eslint-plugin
等。而之前的两个 lint 解决方案都将弃用:
typescript-eslint-parser
已停止维护
TSLint
将提供迁移工具,并在 typescript-eslint 的功能足够完整后停止维护
TSLint(Once we consider ESLint feature-complete w.r.t. TSLint, we will
deprecate TSLint and help users migrate to ESLint1)
综上所述,目前以及将来的 TypeScript 的代码检查方案就是 typescript-eslint。
什么是代码检查
代码检查主要是用来发现代码错误、统一代码风格。
在 JavaScript 项目 ...
声明合并
如果定义了两个相同名字的函数、接口或类,那么它们会合并成一个类型:
函数的合并
之前学习过,我们可以使用重载定义多个函数类型:
123456789function reverse(x: number): number;function reverse(x: string): string;function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); }}
接口的合并
接口中的属性在合并 ...
类
传统方法中,JavaScript
通过构造函数实现类的概念,通过原型链实现继承。而在 ES6
中,我们终于迎来了 class。
TypeScript 除了实现了所有 ES6
中的类的功能以外,还添加了一些新的用法。
这一节主要介绍类的用法,下一节再介绍如何定义类的类型。
类的概念
虽然 JavaScript 中有类的概念,但是可能大多数 JavaScript
程序员并不是非常熟悉类,这里对类相关的概念做一个简单的介绍。
类(Class):定义了一件事物的抽象特点,包含它的属性和方法
对象(Object):类的实例,通过 new 生成
面向对象(OOP)的三大特性:封装、继承、多态
封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如
Cat ...
枚举
枚举(Enum)类型用于取值被限定在一定范围内的场景,比如一周只能有七天,颜色限定为红绿蓝等。
简单的例子
枚举使用 enum 关键字来定义:
1enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
枚举成员会被赋值为从 0
开始递增的数字,同时也会对枚举值到枚举名进行反向映射:
1234567891011enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};console.log(Days["Sun"] === 0); // trueconsole.log(Days["Mon"] === 1); // trueconsole.log(Days["Tue"] === 2); // trueconsole.log(Days["Sat"] === 6); // trueconsole.log(Days[0] === "Sun"); // trueconsole.log ...
Extended Opportunity -
Mar 2, 2024
A.I Create & Sell Unlimited Audiobooks to 2.3 Million Users -
https://ext-opp.com/ECCO
元组
数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
元组起源于函数编程语言(如 F#),这些语言中会频繁使用元组。
简单的例子
定义一对值分别为 string 和 number
的元组:
1let tom: [string, number] = ['Tom', 25];
当赋值或访问一个已知索引的元素时,会得到正确的类型:
123456let tom: [string, number];tom[0] = 'Tom';tom[1] = 25;tom[0].slice(1);tom[1].toFixed(2);
也可以只赋值其中一项:
12let tom: [string, number];tom[0] = 'Tom';
但是当直接对元组类型的变量进行初始化或者赋值的时候,需要提供所有元组类型中指定的项。
1234567let tom: [string, number];tom = ['Tom', 25];``````let tom: [string, number];tom = ...
