版权声明:转载请说明出处! https://blog.csdn.net/qq_39556143/article/details/84330844
Perl 数据类型:标量(scalar)
0. Perl 的优势和劣势:
- Perl适合在几分钟内写出虽然难看但是却够用的一次性程序;
- Perl擅长处理和文字有关的问题;
- 不适合封闭式二进制可执行文件(opaque binary);
- 标量分类
- 标量数据:(常量) 固定数据,表示确定的数据内容;
- 标量变量:(变量) 可变数据,表示数据的存储容器;
1. 标量数据:数字
Perl处理数字是用的是底层 C 库,并且使用统一的双精度浮点数来存储数据。实际程序中定义的整数在 Perl 内部而言,内部处理时都将其转换为双精度浮点数据来存储和计算。
1.1 整数(dec)
- 直接量(literal),在源代码中直接写生成数据内容的形式。(不就是常量的定义么?)
- 例:0, 2001, -40, 137,23746294269, 314_343_878
- 过长的数字读起来比较吃力,因此允许在整数直接量中加入下划线,仅仅为了方便阅读;
1.2 整数(non-dec)
- 二进制 :以 ‘0b’ 开头,0b1111_1111
- 八进制 :以 ‘0’ 开头,0377
- 十六进制:以 ‘0x’ 开头,0xFF,0xff
1.3 浮点数(float)
- 正常写法:1.25,3.67,78.000
- 科学计数法:-1.5E34,2.5e-12 (十进制中 e 表示以 10 为幂)
- 十六进制浮点数:0x1f.0p3 (十六进制中 p 表示以 2 为幂)
1.4 数字操作符
character | meaning |
---|---|
+ | 2+3 = 5 |
- | 4-2 = 2 |
* | 2*4 = 8 |
/ | 10.2 / 0.3 = 34 |
/ | 10/3 = 3.333333 (perl内部都是双精度浮点数哦) |
% | 10%3 = 1 |
% | 10.5%3.2 = 1 (取模运算:先取整,再求余) |
** | 2**3 = 8 |
2. 标量数据:字符串
- 字符串不限制长短,字符串通常是由可以输出的字母,数字和标点组成,其范围介于ASCII编码的32~126之间;
- Perl完全支持Unicode,但是使用之前必须声明 use utf8;(用于支持ASCII之外的其他字符)
2.1 单引号字符串
- 前后两个 ( ’ ),只是表示字符串的边界,并不是字符串的内容,用于让 Perl 判断字符串的开头和结尾;
- 例: ‘fed’, ‘barney’, ‘’, ’ ’ #3个字符,6个字符,空字符,空格字符
- 单引号中,除( \\ )( \’ )外,其他的都代表字符本身,如<\n>表示字符 \n;
- 单引号中没有转义字符,\\ 和\’ 是为了能够在单引号字符串中使用反斜线 \ 和单引号 ’ .
2.2 双引号字符串
- 前后两个 ( " ),只是表示字符串的边界,并不是字符串的内容,用于让 Perl 判断字符串的开头和结尾;
- 例:“hello”, “hello world\n”, “barney” # “barney” 和 ‘barney’ 是相同的;
- 双引号内的转义字符:
Argument | Meaning |
---|---|
\n | 换行符 |
\r | 回车符 |
\t | 水平制表符 |
\f | 换页符 |
\b | 退格 |
\a | 系统响铃 |
\e | 跳出(ASCII编码的转义字符) |
\007 | 八进制表示的ASCII值 |
\x7f | 十六进制表示的ASCII值 |
\x{2744} | 十六进制表示的Unicode代码点(这里代表❉) |
\N{CHARACTER NAME} | 任何一个Unicode代码点 |
\cC | 控制符 Control 按键的代码,\cC代表用时按下Control+C |
\\ | 反斜线 |
\" | 双引号 |
\l | 将下个字母转换为小写 |
\L | 将后面的字符都转为小写,直到 \E 为止 |
\u | 将下个字母转为大写 |
\U | 将后面的字符都转为大写,直到 \E 为止 |
\Q | 将后面的字符非单词都加上反斜线,直到 \E 为止 |
\E | 结束 \L, \U, \Q的作用范围 |
2.3 字符串操作符
Argument | Meaning |
---|---|
. | 拼接符“hello”.“world” -> “helloworld” |
. | 拼接符“hello”." ",“world” -> “hello world” |
x | 小写字母 x,“fred”x3 ->“fredfredfred” |
x | 5x4 -> "5"x4 -> “5555” (字符串操作,先转换为字符串) |
x | 5x4.8 -> 5x4 -> “5555” (先向下取整,再进行字符串重复操作) |
3. 数字和字符串的转换
- Perl 会自动转换数字和字符串数据,转换原则取决于操作符的意义,不用手动转换。
- 数字操作符:转换为数字 -> 计算
- 字符串操作符:转换为字符串 -> 处理
- 例:
- “12” * “3” ->36
- “12fred67” * “3” -> 36 (非数字部分被忽略,如果加了-w,会报警告)
- “fred” * “3” -> 0 (不包含数字的字符串被转换为零,如果加了-w,会报警告)
- 非十进制的转换:
- 如果有一个以其他进制表示的数字字符串,可以采用 hex() 和 oct() 将字符串转换为对应的数字;
- hex() 只能用于转换十六进制字符串 -> 数字;oct() 可以灵活的转换十六,八,二进制字符串 -> 数字;
Argument | Meaning |
---|---|
hex(‘DEADBEEF’) | 十进制数字3_735_928_559 |
hex(‘0xDEADBEFF’) | 十进制数字3_735_928_559 |
hex(10) | 十进制10 -> 字符串“10” -> 16 (字符串操作符,先将十进制数字10转换为字符串) |
hex(0x10) | 十六进制数字10 -> 字符串“16” -> 22(字符串操作符,先将十六进制数字10转换为字符串) |
oct(‘0377’) | 十进制数字 255 |
oct(‘377’) | 十进制数字 255 |
oct(‘0xDEADBEFF’) | 十进制数字3_735_928_559 (0x) |
oct(‘0b1101’) | 十进制13 (0b) |
oct(“0b$bits”) | 将变量$bits中的数字转换为十进制数字 |
4. 标量变量
- 所谓变量,就是存储一个值或多个值的容器,而标量变量是指存储一个值的变量。
- 在 Perl 中,标量变量以美元符号 $ 开头,这个符号也被称为魔符(sigil), 其后是变量的 Perl 标识符:由下划线和字母开头,后跟多个字母,数字和下划线。
- 标识符是区分大小写的,$fred 和$Fred 是完全不同的两个标识符。
- Perl 不仅支持ASCII的字符作为变量,如果启用了utf-8,那么可以用 Unicode 表示;
- Perl中$符号的意思是 “取单个东西” 或者 “取标量” ,魔符不意味着变量类型,而是代表取数据的方式。
4.1 复合赋值操作符
#复合赋值操作符
$fred = $fred + 5; #不使用复合赋值操作符
$fred += 5; #使用复合赋值操作符
$fred *= 3; #代表 $fred的值乘3
$fred **= 3; #$fred的三次方
$str .= " "; #字符串操作符也可以
4.2 用print输出结果
我们可以使用print操作符,将内容输出到外部,他可以接受标量值作为参数,然后不经修饰地将它传送到标准输出(standard output).
# print 操作符
print "hello world\n"; #输出 hello world, 后面接着换行符
print "The answer is " #连续三句输出语句
print 6 * 7;
print ".\n";
print "The answer is ", 6 * 7, ".\n"; #此句和上述三句的输出结果相同
# say 操作符
# perl v5.10 之后,新增的改良版print函数
say "hello world"; #输出时,自动在行尾增加换行符
4.3 字符串中的变量内插
一般使用双引号字符串时,希望把其中的变量替换成变量当前的内容,从而成为新的字符擦混,这个过程称为变量内插;变量内插只能用于双引号圈起来的字符串中,单引号中不能使用,因此也被称为双引号内插。
#1 双引号内插 ""
$meal = "steak";
$barney = "fred ate a $meal"; #OUTPUT: fred ate a steak
$barney = 'fred ate a $meal'; #OUTPUT: fred ate a $meal
print $fred;
print "$fred"; #这两句输出结果相同
#2 不希望使用变量内插时
$barney = "fred ate a \$meal"; #OUTPUT: fred ate a $meal
$barney = 'fred ate a $meal'; #OUTPUT: fred ate a $meal
#3 如果使用变量内插时,需要紧跟其后增加其他合法的字符
$what = "steak";
$whats = "";
$n = 3;
print "fred ate $n $whats.\n"; #OUTPUT: fred ate 3 .
print "fred ate $n ${what}s.\n"; #OUTPUT: fred ate 3 steaks. (利用花括号帮助perl判断边界)
print "fred ate $n $what"."s.\n"; #OUTPUT: fred ate 3 steaks. (麻烦的写法)
print 'fred ate '.$n.' '.$what."s\n"; #OUTPUT: fred ate 3 steaks. (蛋疼的写法)
4.4 用代码点创建字符
有时候我们需要输入一些键盘上没有的字符,如❉,α,β等,与其通过输入或文本编辑器输入太特殊字符,不如直接输入字符的代码点(code point);
#函数:chr() Unicode -> Character
$alpha = chr(hex('03B1')); #$alpah = α
#函数:ard() Character -> Unicode
$code_point = ord('α');
4.5 比较操作符
- Perl 的比较操作符
- 数字:==,!=,<,>,<=,>=
- 字符:eq, ne, lt,gt,le, ge
5 控制结构
5.1 if 控制结构
通过判断条件,决定执行哪个分支的语句;
# if 结构中用花括号{}表示边界;花括号外部不需要分号;
#################### if structure 1 ########################
if ($name gt 'fred') {
print "'$name' is comes after 'fred' in sorted oeder.\n";
}
#################### if structure 2 ########################
if ($name gt 'fred') {
print "'$name' is comes after 'fred' in sorted oeder.\n";
} else {
print "'$name' is comes before 'fred' in sorted oeder.\n";
print "Maybe they are the same string, in fact.\n";
}
5.2 while 控制结构
while 结构需要先判断条件,条件满足后执行循环语句;
# while结构同样以花括号{}作为边界;花括号外部不需要加分号;
# 如果while的初始条件为假,直接略过;
$cnt = 0;
while ($cnt < 10) {
$cnt += 2;
print "counter is now $cnt.\n"; #依次打印2 4 6 8 10
}
5.3 布尔逻辑值
(1)Perl 语言中没有专用的 boolean 逻辑数据类型,其真假判断方式如下:
- 数字:0为假,其他为真;
- 字符串:空字符串 (’’) 和字符串 ‘0’ 返回假, 其他所有字符串值为真;
- 变量未赋值:返回假。
(2)要取得相反的逻辑值,可以使用 !单目取反操作符:
- 如果其后的操作数为真,就返回假;
- 如果其后的操作数为假,就返回真;
小技巧 :因为 Perl 中没有专门的布尔类型的变量,但是 !总会返回某个代表真假的标量值,那么我们可以使用连续两次的 !!,得到布尔逻辑的变量:
#Larry并没有表示可以这样使用,但是这样用暂时不会出现问题
$still_true = !! 'fred';
$still_false = !! '0';
5.4 获取用户输入和chomp操作符
- 每次当代码运行到 <STDIN> 时,Perl 就会从标准输入设备读取完整的一行标量值,即第一个换行符前所有的内容,此内容就会成为<STDIN>上的值。
- 当程序运行到<STDIN>时,Perl 程序会停下来等待用户输入,直到看到换行符(回车);
- 从<STDIN>中读取的字符串是包含换行符的,我们可以利用这一点判断输入是否为空行;
- chomp操作符:
- chomp操作符,用于去除字符串末尾的最后一个换行符;
- 行尾没有换行符,不做任何操作;
- 行尾有多个换行符,只去掉最后一个;
- 行尾只有一个换行符,去掉该换行符;
- 返回值为实际移除的字符数;
# 标准输入<STDIN>的用法
$line = <STDIN>;
if ($line eq "\n") {
print "That was just a blank line.\n";
} else {
print "The input line was: $line";
}
#chomp函数的常见用法
chomp($line = <STDIN>); #读取不带换行符的输入
5.5 undef值和defined函数
- 在首次赋值之前,变量的初始值就是 undef,表示未定义:
- 用作数字:undef -> 0
- 用作字符串:undef -> ‘’
由于这个性质,我们看可以不预先声明变量的初始值,就直接使用:
#累加器
$n = 1;
while ($n < 10) {
$sum += $n;
$n += 2;
}
print "The total sum is: $sum.\n";
许多操作符在参数越界,或者参数不合理时会返回 undef,然后可能继而用零或者空字符串运行。
- 行输入符<STDIN>有时候会返回undef:
- 正常情况:读取一行文本;
- 文件末尾:空文本返回undef;
- 要判断某个字符是否为undef,可以使用函数defined():
- 未定义 -> 返回假;
- 已定义 -> 返回真;(定义0 和空字符串也会返回真)
#defined function
$next_line = <STDIN>;
if (defined($next_line)) {
print "The input is : $next_line";
} else {
print "No input!\n";
}
#用户自定义undef
$next_line = undef; #回到虚无,仿佛从来没用过