0%

原文链接
注:以下全部代码的执行环境为VC++ 6.0

在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这项工作,您的代码可能是:

1
2
3
4
5
6
7
#define MON  1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7

在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。

1. 定义一种新的数据类型 - 枚举型

以下代码定义了这种新的数据类型 - 枚举型

1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};

(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。

(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。

(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。

(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。

(5) 枚举型是预处理指令#define的替代。

(6) 类型定义以分号;结束。

2. 使用枚举类型对变量进行声明

新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float, 双精度浮点型double, 字符型char, 短整型short等等。用这些基本数据类型声明变量通常是这样:

1
2
3
4
5
6
7
8
char     a; //变量a的类型均为字符型char
char letter;
int x,
y,
z; //变量x,y和z的类型均为整型int
int number;
double m, n;
double result; //变量result的类型为双精度浮点型double

既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。

方法一:枚举类型的定义和变量的声明分开

1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
1
2
3
4
enum DAY yesterday;
enum DAY today;
enum DAY tomorrow; //变量tomorrow的类型为枚举型enum DAY
enum DAY good_day, bad_day; //变量good_day和bad_day的类型均为枚举型enum DAY

方法二:类型定义与变量声明同时进行:

1
2
3
4
5
6
7
8
9
10
enum //跟第一个定义不同的是,此处的标号DAY省略,这是允许的。
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //变量workday的类型为枚举型enum DAY
1
enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days; //变量days的类型为枚举型enum week
1
enum BOOLEAN { false, true } end_flag, match_flag; //定义枚举类型并声明了两个枚举型变量

方法三:用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明:

1
2
3
4
5
6
7
8
9
10
typedef enum workday
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //此处的workday为枚举型enum workday的别名
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

enum workday中的workday可以省略:

1
2
3
4
5
6
7
8
9
10
typedef enum
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //此处的workday为枚举型enum workday的别名
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

也可以用这种方式:

1
2
3
4
5
6
7
8
9
10
typedef enum workday
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
};
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。错误示例如下所示:

$\color{red}{错误声明一:}$存在同名的枚举类型

1
2
3
4
5
6
typedef enum
{
wednesday,
thursday,
friday
} workday;
1
2
3
4
5
6
typedef enum WEEK
{
saturday,
sunday = 0,
monday,
} workday;

$\color{red}{错误声明二:}$存在同名的枚举成员

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef enum
{
wednesday,
thursday,
friday
} workday_1;

typedef enum WEEK
{
wednesday,
sunday = 0,
monday,
} workday_2;

3.使用枚举类型的变量

3.1 对枚举型的变量赋值。

实例将枚举类型的赋值与基本数据类型的赋值进行了对比:

方法一:先声明变量,再对变量赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>

/* 定义枚举类型 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
/* 使用基本数据类型声明变量,然后对变量赋值 */
int x, y, z;

x = 10;
y = 20;
z = 30;

/* 使用枚举类型声明变量,再对枚举型变量赋值 */
enum DAY yesterday, today, tomorrow;

yesterday = MON;
today = TUE;
tomorrow = WED;

printf("%d %d %d \n", yesterday, today, tomorrow);
}

方法二:声明变量的同时赋初值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

/* 定义枚举类型 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
/* 使用基本数据类型声明变量同时对变量赋初值 */
int x=10, y=20, z=30;

/* 使用枚举类型声明变量同时对枚举型变量赋初值 */
enum DAY yesterday = MON,
today = TUE,
tomorrow = WED;

printf("%d %d %d \n", yesterday, today, tomorrow);
}

方法三:定义类型的同时声明变量,然后对变量赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

/* 定义枚举类型,同时声明该类型的三个变量,它们都为全局变量 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } yesterday, today, tomorrow;

/* 定义三个具有基本数据类型的变量,它们都为全局变量 */
int x, y, z;

void main()
{
/* 对基本数据类型的变量赋值 */
x = 10; y = 20; z = 30;

/* 对枚举型的变量赋值 */
yesterday = MON;
today = TUE;
tomorrow = WED;

printf("%d %d %d \n", x, y, z); //输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
}

方法四:类型定义,变量声明,赋初值同时进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

/* 定义枚举类型,同时声明该类型的三个变量,并赋初值。它们都为全局变量 */
enum DAY
{
MON=1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}
yesterday = MON, today = TUE, tomorrow = WED;

/* 定义三个具有基本数据类型的变量,并赋初值。它们都为全局变量 */
int x = 10, y = 20, z = 30;

void main()
{
printf("%d %d %d \n", x, y, z); //输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
}

3.2 对枚举型的变量赋整数值时,需要进行类型转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
enum DAY yesterday, today, tomorrow;

yesterday = TUE;
today = (enum DAY) (yesterday + 1); //类型转换
tomorrow = (enum DAY) 30; //类型转换
//tomorrow = 3; //错误

printf("%d %d %d \n", yesterday, today, tomorrow); //输出:2 3 30
}

3.3 使用枚举型变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<stdio.h>

enum
{
BELL = '\a',
BACKSPACE = '\b',
HTAB = '\t',
RETURN = '\r',
NEWLINE = '\n',
VTAB = '\v',
SPACE = ' '
};

enum BOOLEAN { FALSE = 0, TRUE } match_flag;

void main()
{
int index = 0;
int count_of_letter = 0;
int count_of_space = 0;

char str[] = "I'm Ely efod";

match_flag = FALSE;

for(; str[index] != '\0'; index++)
if( SPACE != str[index] )
count_of_letter++;
else
{
match_flag = (enum BOOLEAN) 1;
count_of_space++;
}

printf("%s %d times %c", match_flag ? "match" : "not match", count_of_space, NEWLINE);
printf("count of letters: %d %c%c", count_of_letter, NEWLINE, RETURN);
}

输出:

1
2
3
match 2 times
count of letters: 10
Press any key to continue

4. 枚举类型与sizeof运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>

enum escapes
{
BELL = '\a',
BACKSPACE = '\b',
HTAB = '\t',
RETURN = '\r',
NEWLINE = '\n',
VTAB = '\v',
SPACE = ' '
};

enum BOOLEAN { FALSE = 0, TRUE } match_flag;

void main()
{
printf("%d bytes \n", sizeof(enum escapes)); //4 bytes
printf("%d bytes \n", sizeof(escapes)); //4 bytes

printf("%d bytes \n", sizeof(enum BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(match_flag)); //4 bytes

printf("%d bytes \n", sizeof(SPACE)); //4 bytes
printf("%d bytes \n", sizeof(NEWLINE)); //4 bytes
printf("%d bytes \n", sizeof(FALSE)); //4 bytes
printf("%d bytes \n", sizeof(0)); //4 bytes
}

5. 综合举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<stdio.h>

enum Season
{
spring, summer=100, fall=96, winter
};

typedef enum
{
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
Weekday;

void main()
{
/* Season */
printf("%d \n", spring); // 0
printf("%d, %c \n", summer, summer); // 100, d
printf("%d \n", fall+winter); // 193

Season mySeason=winter;
if(winter==mySeason)
printf("mySeason is winter \n"); // mySeason is winter

int x=100;
if(x==summer)
printf("x is equal to summer\n"); // x is equal to summer

printf("%d bytes\n", sizeof(spring)); // 4 bytes

/* Weekday */
printf("sizeof Weekday is: %d \n", sizeof(Weekday)); //sizeof Weekday is: 4

Weekday today = Saturday;
Weekday tomorrow;
if(today == Monday)
tomorrow = Tuesday;
else
tomorrow = (Weekday) (today + 1); //remember to convert from int to Weekday
}

ubuntu关机和重启命令

linux下常用的关机命令有:shutdown、halt、poweroff、init;重启命令有:reboot。下面本文就主要介绍一些常用的关机命令以及各种关机命令之间的区别和具体用法。

阅读全文 »

Linux下的压缩解压缩命令详解及实例

实例:压缩服务器上当前目录的内容为xxx.zip文件

1
zip -r xxx.zip ./*

解压zip文件到当前目录
1
unzip filename.zip

另:有些服务器没有安装zip包执行不了zip命令,但基本上都可以用tar命令的,实例如下:

1
tar -zcvf /home/zdzlibs.tar.gz /home/zdz/java/zdzlibs/

linux zip命令

zip -r myfile.zip ./*
将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件.

2.unzip
unzip -o -d /home/sunny myfile.zip
把myfile.zip文件解压到 /home/sunny/
-o:不提示的情况下覆盖文件;
-d:-d /home/sunny 指明将文件解压缩到/home/sunny目录下;

3.其他
zip -d myfile.zip smart.txt
删除压缩文件中smart.txt文件
zip -m myfile.zip ./rpm_info.txt

向压缩文件中myfile.zip中添加rpm_info.txt文件

要使用 zip 来压缩文件,在 shell 提示下键入下面的命令:

zip -r filename.zip filesdir

在这个例子里,filename.zip 代表你创建的文件,filesdir 代表你想放置新 zip 文件的目录。-r 选项指定你想递归地(recursively)包括所有包括在 filesdir 目录中的文件。

要抽取 zip 文件的内容,键入以下命令:

unzip filename.zip

你可以使用 zip 命令同时处理多个文件和目录,方法是将它们逐一列出,并用空格间隔:

zip -r filename.zip file1 file2 file3 /usr/work/school

上面的命令把 file1、file2、 file3、以及 /usr/work/school 目录的内容(假设这个目录存在)压缩起来,然后放入 filename.zip 文件中。

tar 命令详解

  -c: 建立压缩档案

  -x:解压

  -t:查看内容

  -r:向压缩归档文件末尾追加文件

  -u:更新原压缩包中的文件

  这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。

  -c: 建立压缩档案

  -x:解压

  -t:查看内容

  -r:向压缩归档文件末尾追加文件

  -u:更新原压缩包中的文件

  下面的参数-f是必须的

  -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。

  # tar -cf all.tar *.jpg

  这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。

  # tar -rf all.tar *.gif

  这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。

  # tar -uf all.tar logo.gif

  这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。

  # tar -tf all.tar

  这条命令是列出all.tar包中所有文件,-t是列出文件的意思

  # tar -xf all.tar

  这条命令是解出all.tar包中所有文件,-t是解开的意思

  压缩

  tar –cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg

  tar –czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz

  tar –cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2

  tar –cZf jpg.tar.Z *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z

  rar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for linux

  zip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux

  解压

  tar –xvf file.tar //解压 tar包

  tar -xzvf file.tar.gz //解压tar.gz

  tar -xjvf file.tar.bz2 //解压 tar.bz2

  tar –xZvf file.tar.Z //解压tar.Z

  unrar e file.rar //解压rar

  unzip file.zip //解压zip

  总结

  1、*.tar 用 tar –xvf 解压

  2、*.gz 用 gzip -d或者gunzip 解压

  3、.tar.gz和.tgz 用 tar –xzf 解压

  4、*.bz2 用 bzip2 -d或者用bunzip2 解压

  5、*.tar.bz2用tar –xjf 解压

  6、*.Z 用 uncompress 解压

  7、*.tar.Z 用tar –xZf 解压

  8、*.rar 用 unrar e解压

  9、*.zip 用 unzip 解压

  Linux中tar命令详解(转载的资料)

  2008年04月17日 星期四 15:37

  tar命令

  tar 可以为文件和目录创建档案。利用tar,用户可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件。tar最初被 用来在磁带上创建档案,现在,用户可以在任何设备上创建档案,如软盘。利用tar命令,可以把一大堆的文件和目录全部打包成一个文件,这对于备份文件或将 几个文件组合成为一个文件以便于网络传输是非常有用的。Linux上的tar是GNU版本的。

  语法:tar [主选项+辅选项] 文件或者目录

  使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用。

  主选项:

  c 创建新的档案文件。如果用户想备份一个目录或是一些文件,就要选择这个选项。

  r 把要存档的文件追加到档案文件的未尾。例如用户已经作好备份文件,又发现还有一个目录或是一些文件忘记备份了,这时可以使用该选项,将忘记的目录或文件追加到备份文件中。

  t 列出档案文件的内容,查看已经备份了哪些文件。

  u 更新文件。就是说,用新增的文件取代原备份文件,如果在备份文件中找不到要更新的文件,则把它追加到备份文件的最后。

  x 从档案文件中释放文件。

  辅助选项:

  b 该选项是为磁带机设定的。其后跟一数字,用来说明区块的大小,系统预设值为20(20*512 bytes)。

  f 使用档案文件或设备,这个选项通常是必选的。

  k 保存已经存在的文件。例如我们把某个文件还原,在还原的过程中,遇到相同的文件,不会进行覆盖。

  m 在还原文件时,把所有文件的修改时间设定为现在。

  M 创建多卷的档案文件,以便在几个磁盘中存放。

  v 详细报告tar处理的文件信息。如无此选项,tar不报告文件信息。

  w 每一步都要求确认。

  z 用gzip来压缩/解压缩文件,加上该选项后可以将档案文件进行压缩,但还原时也一定要使用该选项进行解压缩。

  Linux下的压缩文件剖析

  对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕。别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rap。可是Linux就不同了,它有.gz、.tar.gz、tgz、bz2、.Z、.tar等众多的 压缩文件名,此外windows下的.zip和.rar也可以在Linux下使用,不过在Linux使用.zip和.rar的人就太少了。本文就来对这些 常见的压缩文件进行一番小结,希望你下次遇到这些文件时不至于被搞晕。

  在具体总结各类压缩文件之前呢,首先要弄清两个概念:打包和压缩。打包是指将一大堆文件或目录什么的变成一个总的文件,压缩则是将一个大的文件通过一些压 缩算法变成一个小文件。为什么要区分这两个概念呢?其实这源于Linux中的很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你就 得先借助另它的工具将这一大堆文件先打成一个包,然后再就原来的压缩程序进行压缩。

  Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的。生成tar包后,就可以用其它的程序来进行压缩了,所以首先就来讲讲tar命令的基本用法:

  tar命令的选项有很多(用man tar可以查看到),但常用的就那么几个选项,下面来举例说明一下:

  # tar -cf all.tar *.jpg

  这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。

  # tar -rf all.tar *.gif

  这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。

  # tar -uf all.tar logo.gif

  这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。

  # tar -tf all.tar

  这条命令是列出all.tar包中所有文件,-t是列出文件的意思

  # tar -xf all.tar

  这条命令是解出all.tar包中所有文件,-t是解开的意思

  以上就是tar的最基本的用法。为了方便用户在打包解包的同时可以压缩或解压文件,tar提供了一种特殊的功能。这就是tar可以在打包或解包的同时调用其它的压缩程序,比如调用gzip、bzip2等。

  1) tar调用gzip

  gzip是GNU组织开发的一个压缩程序,.gz结尾的文件就是gzip压缩的结果。与gzip相对的解压程序是gunzip。tar中使用-z这个参数来调用gzip。下面来举例说明一下:

  # tar -czf all.tar.gz *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用gzip压缩,生成一个gzip压缩过的包,包名为all.tar.gz

  # tar -xzf all.tar.gz

  这条命令是将上面产生的包解开。

  2) tar调用bzip2

  bzip2是一个压缩能力更强的压缩程序,.bz2结尾的文件就是bzip2压缩的结果。与bzip2相对的解压程序是bunzip2。tar中使用-j这个参数来调用gzip。下面来举例说明一下:

  # tar -cjf all.tar.bz2 *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用bzip2压缩,生成一个bzip2压缩过的包,包名为all.tar.bz2

  # tar -xjf all.tar.bz2

  这条命令是将上面产生的包解开。

  3)tar调用compress

  compress也是一个压缩程序,但是好象使用compress的人不如gzip和bzip2的人多。.Z结尾的文件就是bzip2压缩的结果。与 compress相对的解压程序是uncompress。tar中使用-Z这个参数来调用gzip。下面来举例说明一下:

  # tar -cZf all.tar.Z *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用compress压缩,生成一个uncompress压缩过的包,包名为all.tar.Z

  # tar -xZf all.tar.Z

  这条命令是将上面产生的包解开

  有了上面的知识,你应该可以解开多种压缩文件了,下面对于tar系列的压缩文件作一个小结:

  1)对于.tar结尾的文件

  tar -xf all.tar

  2)对于.gz结尾的文件

  gzip -d all.gz

  gunzip all.gz

  3)对于.tgz或.tar.gz结尾的文件

  tar -xzf all.tar.gz

  tar -xzf all.tgz

  4)对于.bz2结尾的文件

  bzip2 -d all.bz2

  bunzip2 all.bz2

  5)对于tar.bz2结尾的文件

  tar -xjf all.tar.bz2

  6)对于.Z结尾的文件

  uncompress all.Z

  7)对于.tar.Z结尾的文件

  tar -xZf all.tar.z

  另外对于Window下的常见压缩文件.zip和.rar,Linux也有相应的方法来解压它们:

  1)对于.zip

  linux下提供了zip和unzip程序,zip是压缩程序,unzip是解压程序。它们的参数选项很多,这里只做简单介绍,依旧举例说明一下其用法:

  # zip all.zip *.jpg

  这条命令是将所有.jpg的文件压缩成一个zip包

  # unzip all.zip

  这条命令是将all.zip中的所有文件解压出来

  2)对于.rar

  要在linux下处理.rar文件,需要安装RAR for Linux,可以从网上下载,但要记住,RAR for Linux

  不是免费的;然后安装:

  # tar -xzpvf rarlinux-3.2.0.tar.gz

  # cd rar

  # make

  这样就安装好了,安装后就有了rar和unrar这两个程序,rar是压缩程序,unrar是解压程序。它们的参数选项很多,这里只做简单介绍,依旧举例说明一下其用法:

  # rar a all *.jpg

  这条命令是将所有.jpg的文件压缩成一个rar包,名为all.rar,该程序会将.rar 扩展名将自动附加到包名后。

  # unrar e all.rar

  这条命令是将all.rar中的所有文件解压出来

  到此为至,我们已经介绍过linux下的tar、gzip、gunzip、bzip2、bunzip2、compress、uncompress、 zip、unzip、rar、unrar等程式,你应该已经能够使用它们对.tar、.gz、.tar.gz、.tgz、.bz2、.tar.bz2、. Z、.tar.Z、.zip、.rar这10种压缩文件进行解压了,以后应该不需要为下载了一个软件而不知道如何在Linux下解开而烦恼了。而且以上方 法对于Unix也基本有效。

  本文介绍了linux下的压缩程式tar、gzip、gunzip、bzip2、bunzip2、 compress、uncompress、zip、unzip、rar、unrar等程式,以及如何使用它们对.tar、.gz、.tar.gz、. tgz、.bz2、.tar.bz2、.Z、.tar.Z、.zip、.rar这10种压缩文件进行操作

要查看Ubuntu操作系统的位数是32位还是64位,可以通过以下命令来查看:

查看long的位数,返回32或64

可以在终端terminal下输入命令:

1
getconf LONG_BIT

输出结果
1
32

2018-01-16 20-46-51屏幕截图.png
也可以输入:
1
uname -a

输出结果:
1
Linux jacklu 4.13.0-26-generic #29~16.04.2-Ubuntu SMP Tue Jan 9 21:38:24 UTC 2018 i686 i686 i686 GNU/Linux

2018-01-16 20-47-17屏幕截图.png

查看Ubuntu版本:

方法一

在终端中执行下列指令:

1
cat /etc/issue

可以查看当前正在运行的 Ubuntu 的版本号。其输出结果类似下面的内容:
1
Ubuntu 16.04.3 LTS \n \l

2018-01-16 20-48-47屏幕截图.png

方法二

使用 lsb_release 命令也可以查看 Ubuntu 的版本号,与方法一相比,内容更为详细。执行指令如下:

1
sudo lsb_release -a

将输出结果:
1
2
3
4
5
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

2018-01-16 20-48-27屏幕截图.png

原文链接
1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。
因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的
状态下,其他的用户也可以任意地登录和修改MySQL的信息。可以采用将MySQL对
外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全
状态。最安全的状态是到服务器的Console上面操作,并且拔掉网线。

2.修改MySQL的登录设置:

1
# vim /etc/my.cnf 

[mysqld]的段中加上一句:
1
skip-grant-tables 

例如:
1
2
3
4
[mysqld] 
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-grant-tables

保存并且退出vi。

3.重新启动mysqld

1
2
3
# service mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

4.登录并修改MySQL的root密码
1
2
3
4
5
6
7
8
9
10
11
12
# mysql 
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 3.23.56
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> USE mysql ;
Database changed
mysql> UPDATE user SET Password = password ( 'new-password' ) WHERE User = 'root' ;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2 Changed: 0 Warnings: 0
mysql> flush privileges ;
Query OK, 0 rows affected (0.01 sec)
mysql> quit

5.将MySQL的登录设置修改回来
1
# vim /etc/my.cnf 

将刚才在[mysqld]的段中加上的skip-grant-tables删除
保存并且退出vim

6.重新启动mysqld

1
2
3
# service mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

今天在写一篇博客的时候,遇到使用MathJax公式下标出现问题,然后在网上找到解决办法

出现问题的原因

hexo默认使用hexo-renderer-marked引擎去渲染网页,它会把利用Markdown语法写的文本去转换为相应的html标签。在利用Markdown写MathJax公式的时候,经常会用到下划线_表示下标,但是下划线_会被hexo的默认引擎hexo-renderer-marked渲染成html中的<em>标签,表示斜体,这样一来,我们写的MathJax公式就被错误渲染了,也就没办法正确显示出来。

解决方法

从上面的分析,我们可以知道问题或许出在hexo的渲染引擎上,如果渲染引擎不把公式中的一些特殊字符渲染成html标签,也就避免了这个问题。当然已经有人意识到了这个问题,并且对原先的渲染引擎进行了改进,生成了新的hexo-renderer-kramed引擎,这里是它的Github页面,所以我们只需要卸载默认引擎,并安装这个新的渲染引擎即可。

1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

当我把渲染引擎更换之后,发现大部分公式都正确渲染了,而从网上其他人的叙述中,也同样提到了这个问题,即是行间公式都没有问题,但是个别行内公式还会出现渲染出错,从网上找到了一个方法,解决了这一问题。
定位到你的博客根目录,找到../node_modules/kramed/lib/rules/inline.js文件,
进行部分修改:

1
2
3
4
//escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,      第11行,将其修改为
escape: /^\\([`*\[\]()#$+\-.!_>])/,
//em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, 第20行,将其修改为
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

它取消了该渲染引擎对 \,{,} 的转义,然后再
1
2
hexo clean
hexo g

重新部署,即可解决问题。

另外需要注意一点,对于需要用到MathJax公式的文章,要在Front-matter中打开MathJax开关,例如:

1
2
3
4
5
6
---
date: 2017/8/3 18:20:00
tags: hexo
mathjax: true
title: hexo博客MathJax公式渲染
---

MathJax公式语法

LaTeX语法
下面呢,我整理总结了一番比较常用的MathJax公式语法,同时也可以用来测试一下渲染效果。

>添加公式的方法

1.行内公式

$行内公式$

2.行间公式

$$行间公式$$

>常用的MathJax公式语法

符号 释义 测试用例 最终效果
^{} 上标 x^{y^z}=(1+e^x)^{-2xy^w} $x^{y^z}=(1+e^x)^{-2xy^w}$
_{} 下标 CO_2 $CO_2$
\frac{分子}{分母} or 分子 \over 分母 分数 f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2}) $f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2})$
\sqrt[根指数,省略时为2]{被开方数} 开方 \sqrt{2}、\sqrt[3]{9} $\sqrt{2}$ $\sqrt[3]{9}$
\ldots 与文本底线对齐的省略号 x_1x_2{\ldots}x_n $x_1x_2{\ldots}x_n$
\cdots 与文本中线对齐的省略号 x_1x_2{\cdots}x_n $x_1x_2{\cdots}x_n$
\int_积分下限^积分上限(被积表达式) 积分 \int_1^n{x^2}dx $\int_1^n{x^2}dx$
\sum_{下标表达式}^{上标表达式} {累加表达式} 累加 \sum_{i=1}^n \frac{1}{i^2} $\sum_{i=1}^n \frac{1}{i^2}$
\, or ; or \quad or \qquad 不同宽度的空格 a , b \mid a ; b \mid a \quad b \mid a $\qquad b a,b∣a;b∣ab∣aba,b∣a;b∣ab∣ab$
\color{颜色}{文字} 更改文字颜色 \color{red}{红色} $\color{red}{红色}$

上面的一些基本语法使用了行内公式, 渲染效果没有问题,下面再利用行间公式写一些较为复杂的公式。

分段函数

分段函数格式为

1
f(x)=\begin{cases}语句1\\语句2\\...\end{cases}

\text{文字}中仍可以使用$公式$去插入其他公式,所以可以将其结合分段函数一起使用。

实例:
md文本

1
2
3
4
5
6
 $$ 
f(n)=\begin{cases}
n/2, & \text{如果$ x<=2 $}\\
3n+1, & \text{如果$ x>2 $}
\end{cases}
$$

最终效果:

大括号和小括号

()、[]、{}表示的即是符号本身,使用{}来表示{}。但是如果要显示大号的括号时,需要使用\left和\right命令。

实例:

正常括号
md文本

1
2
3
 $$
f([\frac{1+\{x,y\}}{(\frac{x}{y}+\frac{y}{x})(u+1)}+a]^{3\2})
$$

最终效果

大括号
md文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    $$
f\left(
\left[
\frac{
1+\left\{x,y\right\}
}{
\left(
\frac{x}{y}+\frac{y}{x}
\right)
\left(u+1\right)
}+a
\right]^{3\2}
\right)
$$

最终效果

添加删除线

使用删除线功能必须使用行间公式,删除线分为片段删除线和整段删除线,样式比较多,在这里我只列举一种比较常用的水平删除线,它属于整段删除线的一种。

整段删除线使用\require{enclose}来显示,声明整段删除线后,使用\enclose{删除线效果}{字符}来实现删除线效果,而水平删除线效果用关键字horizontalstrike。

实例:

md文本

1
2
3
4
5
6
$$
\require{enclose}\begin{array}{}
\enclose{horizontalstrike}{x+y}\\
\enclose{horizontalstrike}{x*y}\\
\end{array}
$$

最终效果

对齐

\begin{align}用于开头,\end{align}用于结尾,对齐的位置用&开始,用\\结束
输入:

1
2
3
4
5
6
$$
\begin{align}
f(x) &=a+b+a\\
& = 2a+b
\end{align}
$$

输出:

减法器有两种:一种是先对输入信号实现反相,然后再做加法运算;另一种是直接利用差分电路实现

1.输入信号实现反相实现减法器

543cf225x7ca35edcb97b&690.jpg

2.差分电路实现减法器

543cf225x72dd2aab7ff5&690.jpg
我使用差分减法器比较多,主要用于电流、电压的测量
其计算输出电压的公式如下:

若令R1=R2,R3=R4,上式可简化为:

当你使用3.3V的单片机的时候,电平转换就在所难免了,经常会遇到3.3转5V或者5V转3.3V的情况,这里介绍一个简单的电路,他可以实现两个电平的相互转换(注意是相互哦,双向的,不是单向的!).电路十分简单,仅由3个电阻加一个MOS管构成。

  电路图如下:
1

上图中,S1,S2为两个信号端,VCC_S1和VCC_S2为这两个信号的高电平电压.另外限制条件为:
  1,VCC_S1<=VCC_S2.
  2,S1的低电平门限大于0.7V左右(视NMOS内的二极管压降而定).
  3,Vgs<=VCC_S1.
  4,Vds<=VCC_S2
  对于3.3V和5V/12V等电路的相互转换,NMOS管选择AP2306即可.原理比较简单,大家自行分析吧!此电路我已在多处应用,效果很好.

2

I2C
  类似这种吧,只是不知道这种电路的速率能达到多少
  电平转换器的操作
  在电平转换器的操作中要考虑下面的三种状态:
  1. 没有器件下拉总线线路。“低电压”部分的总线线路通过上拉电阻Rp 上拉至3.3V。 MOS-FET 管的门极和源极都是3.3V, 所以它的VGS 低于阀值电压,MOS-FET 管不导通。这就允许“高电压”部分的总线线路通过它的上拉电阻Rp 拉到5V。 此时两部分的总线线路都是高电平,只是电压电平不同。
  2. 一个3.3V器件下拉总线线路到低电平。MOS-FET管的源极也变成低电平,而门极是3.3V。VGS上升高于阀值,MOS-FET管开始导通。然后“高电压”部分的总线线路通过导通的MOS-FET管被3.3V器件下拉到低电平。此时,两部分的总线线路都是低电平,而且电压电平相同。
  3. 一个5V的器件下拉总线线路到低电平。MOS-FET管的漏极基底二极管“低电压”部分被下拉直到VGS超过阀值,MOS-FET管开始导通。“低电压”部分的总线线路通过导通的MOS-FET管被5V的器件进一步下拉到低电平。此时,两部分的总线线路都是低电平,而且电压电平相同。
  这三种状态显示了逻辑电平在总线系统的两个方向上传输,与驱动的部分无关。状态1执行了电平转换功能。状态2和3按照I2C总线规范的要求在两部分的总线线路之间实现“线与”的功能。
  除了3.3V VDD1和5V VDD2的电源电压外,还可以是例如:2V VDD1和10V VDD2。在正常操作中,VDD2必须等于或高于VDD1(在开关电源时允许VDD2低于VDD1)。
  MOS-N场效应管双向电平转换电路—适用于低频信号电平转换的简单应用
  
3

如上图所示,是MOS-N场效应管双向电平转换电路。
  双向传输原理:
  为了方便讲述,定义 3.3V 为 A 端,5.0V 为 B 端。
  A端输出低电平时(0V),MOS管导通,B端输出是低电平(0V)
  A端输出高电平时(3.3V),MOS管截至,B端输出是高电平(5V)
  A端输出高阻时(OC) ,MOS管截至,B端输出是高电平(5V)
  B端输出低电平时(0V),MOS管内的二极管导通,从而使MOS管导通,A端输出是低电平(0V)
  B端输出高电平时(5V),MOS管截至,A端输出是高电平(3.3V)
  B端输出高阻时(OC) ,MOS管截至,A端输出是高电平(3.3V)
  优点:
  1、适用于低频信号电平转换,价格低廉。
  2、导通后,压降比三极管小。
  3、正反向双向导通,相当于机械开关。
  4、电压型驱动,当然也需要一定的驱动电流,而且有的应用也许比三极管大。

1. 电阻桥定义解释

惠斯通电桥是由四个电阻组成的电桥电路,这四个电阻分别叫做电桥的桥臂,惠斯通电桥利用电阻的变化来测量物理量的变化,单片机采集可变电阻两端的电压然后处理,就可以计算出相应的物理量的变化,是一种精度很高的测量方式。其电路形式如下图所示。

110945pzcuhva3gm2cpncy

在电桥中有三个电阻阻值是固定的分别为R1,R2,R3,第四个电阻是可变的为Rx,Rx发生变化时,图中B,D两点之间的电压发生变化,通过采集电压的变化就可以知道环境中物理量的变化,而从实现测量的目的。下面举例介绍电桥电路的计算方式。

2. 电阻桥相关计算

假设流过R1,R2桥臂的电流为I1,流过R3,Rx桥臂的电流为I2,电桥供电电压为VCC,如下图所示。
fig1
通过欧姆定律可以计算出每个电阻两端的电压。在R1和R2这两个桥臂上,R1,R2将VCC电压分压,R2电阻两端得到的电压即为V1;在R3和Rx这个桥臂上,R3,Rx将VCC电压分压,R3电阻两端得到的电压即为V2。下面分别用欧姆定律计算V1和V2。

流过电阻R1和R2的电流I1:

R2两端的电压V1:

流过电阻R3和Rx的电流I2:

R3两端的电压:

V1和V2的电压差:

进一步计算得到:

由此可以看出:
如果4个电阻都相等,即R1=R2=R3=Rx,那么ΔV=0,即电桥处于平衡状态; Rx发生变化会导致△V发生变化;

3.电阻桥的应用

在实际使用中,我们通常将其中三个电阻值固定,而将另外一个电阻换成热敏电阻、压敏电阻、PT100等,这时候就可以用电桥来测物理量了。如果将PT100接入电桥,随着环境温度的变化,PT100的阻值发生变化导致ΔV发生变化,将差分电压ΔV通过差分运放放大后进入单片机的AD采样,再对照PT100的电阻-温度对应表就可以知道当前环境的温度了。

虚短和虚断的概念

由于运放的电压放大倍数很大,一般通用型运算放大器的开环电压放大倍数都在80 dB以上。而运放的输出电压是有限的,一般在 10 V~14 V。因此运放的差模输入电压不足1 mV,两输入端近似等电位,相当于 “短路”。开环电压放大倍数越大,两输入端的电位越接近相等。

“虚短”是指在分析运算放大器处于线性状态时,可把两输入端视为等电位,这一特性称为虚假短路,简称虚短。显然不能将两输入端真正短路。

由于运放的差模输入电阻很大,一般通用型运算放大器的输入电阻都在1MΩ以上。因此流入运放输入端的电流往往不足1uA,远小于输入端外电路的电流。故 通常可把运放的两输入端视为开路,且输入电阻越大,两输入端越接近开路。

“虚断”是指在分析运放处于线性状态时,可以把两输入端视为等效开路,这一特性 称为虚假开路,简称虚断。显然不能将两输入端真正断路。

在分析运放电路工作原理时,首先请各位暂时忘掉什么同向放大、反向放大,什么加法器、减法器,什么差动输入……暂时忘掉那些输入输出关系的公式……这些东东只会干扰你,让你更糊涂﹔也请各位暂时不要理会输入偏置电流、共模抑制比、失调电压等电路参数,这是设计者要考虑的事情。我们理解的就是理想放大器(其实在维修中和大多数设计过程中,把实际放大器当做理想放大器来分析也不会有问题)。

1.反向放大器

img

图一运放的同向端接地=0V,反向端和同向端虚短,所以也是0V,反向输入端输入电阻很高,虚断,几乎没有电流注入和流出,那么R1和R2相当于是串联的,流过一个串联电路中的每一只组件的电流是相同的,即流过R1的电流和流过R2的电流是相同的。
流过R1的电流

流过R2的电流

由虚短得

由虚断得

求解上面的初中代数方程得

这就是传说中的反向放大器的输入输出关系式了。

2.正向放大器

img
图二中Vi与V-虚短,则

因为虚断,反向输入端没有电流输入输出,通过R1和R2 的电流相等,设此电流为I,由欧姆定律得:

Vi等于R2上的分压, 即:

由上得

这就是传说中的同向放大器的公式了。

3.加法器

img
图三中,
由虚断及基尔霍夫定律知,通过R2与R1的电流之和等于通过R3的电流,故

由虚短知:

代入(2)式,(1)式变为

如果取$R1=R2=R3$,则上式变为

这就是传说中的加法器了。

img

由虚断知:运放同向端没有电流流过,则流过R1和R2的电流相等,同理流过R4和R3的电流也相等。故

由虚短知:
如果 ,则由以上式子可以推导出

也是一个加法器!

4.减法器

img
图五由虚断知,通过R1的电流等于通过R2的电流,同理通过R4的电流等于R3的电流,故有

如果$R1=R2$, 则

如果$R3=R4$, 则

由虚短知
所以

这就是传说中的减法器了。

5.积分电路

img
图六电路中
由虚短知,反向输入端的电压与同向端相等
由虚断知,通过R1的电流与通过C1的电流相等。
通过R1的电流

通过C1的电流

所以

输出电压与输入电压对时间的积分成正比,这就是传说中的积分电路了。
若V1为恒定电压U,则上式变换为

t 是时间,则Vout输出电压是一条从0至负电源电压按时间变化的直线。

6.微分电路

img
图七中
由虚断知,通过电容C1和电阻R2的电流是相等的
由虚短知,运放同向端与反向端电压是相等的。则:

这是一个微分电路。
如果V1是一个突然加入的直流电压,则输出Vout对应一个方向与V1相反的脉冲。

7.差分放大电路

img
图八.由虚短知

由虚断知,运放输入端没有电流流过,则R1、R2、R3可视为串联,通过每一个电阻的电流是相同的, 则电流

则:

由虚断知,流过R6与流过R7的电流相等,若$R6=R7$, 则

同理若$R4=R5$,则

由虚短知,

由(5)(7)(8)得

由(4)(9)得

上式中 $\frac{R1+R2+R3}{R2}$是定值,此值确定了差值$(V_y –V_x)$的放大倍数。

这个电路就是传说中的差分放大电路了。

8.电流采集电路

img
分析一个大家接触得较多的电路。很多控制器接受来自各种检测仪表的0~20mA或4~20mA电流,电路将此电流转换成电压后再送ADC转换成数字信号,图九就是这样一个典型电路。如图4~20mA电流流过采样100Ω电阻R1,在R1上会产生0.4~2V的电压差。
由虚断知,运放输入端没有电流流过,则流过R3和R5的电流相等,流过R2和R4的电流相等。故:

由虚短知:

电流从0~20mA变化,则

由(3)(4)式代入(2)式得

如果R3=R2,R4=R5,则由(5)-(1)得

图九中R4/R2=22k/10k=2.2,则f式Vout = -(0.88~4.4)V
即是说,将4~20mA电流转换成了-0.88 ~ -4.4V电压,此电压可以送ADC去处理。

9.恒流源电路

img
电流可以转换成电压,电压也可以转换成电流。图十就是这样一个电路。上图的负反馈没有通过电阻直接反馈,而是串联了三极管Q1的发射结,大家可不要以为是一个比较器就是了。只要是放大电路,虚短虚断的规律仍然是符合的!
由虚断知,运放输入端没有电流流过,

同理

由虚短知 $ V1 = V2 \cdot\cdot\cdot\cdot\cdot\cdot(3) $
如果 $ R2=R6,R4=R5 $,则由(1)(2)(3)式得

上式说明R7两端的电压和输入电压Vi相等,则通过R7的电流

如果负载RL<<100KΩ,则通过Rl和通过R7的电流基本相同。

10.三线制PT100前置放大电路

img
图十一是一个三线制PT100前置放大电路。
PT100传感器引出三根材质、线径、长度完全相同的线,接法如图所示。有2V的电压加在由R14、R20、R15、Z1、PT100及其线电阻组成的桥电路上。Z1、Z2、Z3、D11、D12、D83及各电容在电路中起滤波和保护作用,静态分析时可不予理会,Z1、Z2、Z3可视为短路,D11、D12、D83及各电容可视为开路。
由电阻分压知,

由虚短知,U8B第6、7脚 电压和第5脚电压相等*

由虚断知,U8A第2脚没有电流流过,则流过R18和R19上的电流相等。

由虚断知,U8A第3脚没有电流流过,

在桥电路中R15和Z1、PT100及线电阻串联,PT100与线电阻串联分得的电压通过电阻R17加至U8A的第3脚,

由虚短知,U8A第3脚和第2脚电压相等,*

由abcdef得, (V5-V7)/100=(V7-V3)/2.2 化简得

上式输出电压V5是Rx的函数我们再看线电阻的影响。Pt100最下端线电阻上产生的电压降经过中间的线电阻、Z2、R22,加至U8C的第10脚,
由虚断知,

由虚短知,

由式abc得

由式gh组成的方程组知,如果测出V5、V6的值,就可算出Rx及R0,知道Rx,查pt100分度表就知道温度的大小了。