首页 > 【2017年整理】php单引号和双引号的区别

【2017年整理】php单引号和双引号的区别

2018-03-21 25页 doc 56KB 14阅读

用户头像

is_633808

暂无简介

举报
【2017年整理】php单引号和双引号的区别【2017年整理】php单引号和双引号的区别 php单引号和双引号的区别.txt今天心情不好。我只有四句话想说。包括这句和前面的两句。 我的话说完了对付凶恶的人,就要比他更凶恶;对付卑鄙的人,就要比他更卑鄙没有情人味, 哪来人情味 拿什么整死你,我的爱人。收银员说:没零钱了,找你两个塑料袋吧~ “单 引号和双引号的区别和用法,”现将答案总结了下,写成这篇小短文。 " "双引号里面的字段会经过编译器解释,然后再当作HTML代码输出。 ' '单引号里面的不进行解释,直接输出。 例如: $abc='my name is t...
【2017年整理】php单引号和双引号的区别
【2017年整理】php单引号和双引号的区别 php单引号和双引号的区别.txt今天心情不好。我只有四句话想说。包括这句和前面的两句。 我的话说完了对付凶恶的人,就要比他更凶恶;对付卑鄙的人,就要比他更卑鄙没有情人味, 哪来人情味 拿什么整死你,我的爱人。收银员说:没零钱了,找你两个塑料袋吧~ “单 引号和双引号的区别和用法,”现将答案了下,写成这篇小短文。 " "双引号里面的字段会经过编译器解释,然后再当作HTML代码输出。 ' '单引号里面的不进行解释,直接输出。 例如: $abc='my name is tome'; echo $abc //结果是:my name is tom echo '$abc' //结果是:$abc echo "$abc" //结果是:my name is tom 特别在使用MYSQL语句的时候,双引号和单引号的用法让新手不知所措,在这里,举个例子, 来进行说明。 假设查询条件中使用的是常量,例如: select * from abc_table where user_name='abc'; SQL语句可以写成: SQLstr = "select * from abc_table where user _name= 'abc'" ; 假设查询条件中使用的是变量,例如: $user_name = $_REQUEST['user_name']; //字符串变量 或 $user=array ("name"=> $_REQUEST['user_name‘,"age"=>$_REQUEST['age'];//数组变量 SQL语句就可以写成: SQLstr = "select * from abc_table where user_name = ' " . $user_name . " ' "; SQLstr = "select * from abc_table where user_name = ' " . $user["name"] . " ' "; 对比一下: SQLstr="select * from abc_table where user_name = ' abc ' " ; SQLstr="select * from abc_table where user_name =' " . $user _name . " ' "; SQLstr="select * from abc_table where user_name =' " . $user["name"] . " ' "; SQLstr可以分解为以下3个部分: 1:"select * from table where user_name = ' " //固定SQL语句 2:$user //变量 3:" ' " 1,2,3部分字符串之间用"." 来连接 一、引号定义字符串 在PHP中,通常一个字符串被定义在一对引号中,如: 'I am a string in single quotes' "I am a string in double quotes" PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一 种单或者双 引号来定义开始和结束。例如,下面的字串定义是不合法的: "I am not a valid string since I have unmatching quote marks' 'Me neither!" 定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符 串由双引 号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符, 甚至单引 号。下面的引号串都是合法的: $s = "I am a 'single quote string' inside a double quote string"; $s = 'I am a "double quote string" inside a single quote string'; 当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是: "Why doesn't "this" work?" 实际上被PHP语法分析器分成三个部分: "Why doesn't "——包含一个单引号的双引号串 this——多余的字符,分析器无法处理 " work?" ——普通字符串 上面的这个例子企图在双引号串中包含双引号,而分析器在遇到第二个双引号时便认为字符串结 束了。要达到包含引号的目的,必须分析器在遇到串内普通引号的时候忽略它的原意,我们在引号的 前面加上一个反斜杠来告诉PHP:这个引号是字符串的一部分,正确的是这样: "Why doesn't \"that\" work?" 在英文字符串中一个常见的问题是撇号'的使用,因为它就是一个单引号,而在英文串中十分常见 (英文所有格)。你必须小心处理这些字符: 'You\'d better escape your apostrophes' 可以看到反斜杠在字符串中有他的特殊含义,当我们需要在字符串中包含反斜杠本身时,需要在 该符号前面多加一个反斜杠。例如: $file = "c:\windows\system.ini"; echo $file; // 打印结果为: c:windowssystem.ini system.ini"; $file = "c:\\windows\\ echo $file; // 打印结果为: c:\windows\system.ini 另一种字符串定义方式,能够消除特殊字符的烦恼,而且便于引用较长的文本。该字符串定义方 法以<<<符号紧跟一个自定义字符串开头,最后一行以该自定义字符串结束,并且必须顶格。 二、字串的连接 字串可以使用字串连接符(.)来连接,如: $first_name = 'Charlie'; $last_name = 'Brown'; $full_name = $first_name . ' ' . $last_name; 常见的用途是建立大块的HTML字串代码,赋值号 (=) 连接符 (.) 可以被简写合并为 (.=) 符 号,如: $html = ''; $html .= ''; for ( $i=0 ; $i<10 ; $i++) { $square = $i * $i; $html .= ''; } $html .= '
numbersquare
' . $i . '' . $square . '
'; 三、在字串中使用变量 这个功能让你无须使用连接符号来粘和大量的简单字符串。PHP允许我们在双引号串中直接包含字 串变量,我们可以发现下面的两个字串的处理结果是相同的。 $full_name = $first_name . ' ' . $last_name; $full_name = "$first_name $last_name"; 单引号串和双引号串在PHP中的处理是不相同的。双引号串中的可以被解释而且替换,而单引 号串中的内容总被认为是普通字符。例如: $foo = 2; echo "foo is $foo"; // 打印结果: foo is 2 echo 'foo is $foo'; // 打印结果: foo is $foo echo "foo is $foo\n"; // 打印结果: foo is 2 (同时换行) echo 'foo is $foo\n'; // 打印结果: foo is $foo\n 正如你所看到的,在单引号串中甚至反斜杠也失去了他的扩展含义(除了插入反斜杠\\和插入单 引号\')。所以,当你想在字串中进行变量代换和包含\n(换行符)等转义序列时,你应该使用双引 号。单引号串可以用在其他任何地方,脚本中使用单引号串处理速度会更快些,因为PHP语法分析器对 单引号串的处理方式比较单纯,而双引号的处理由于串内部也需要解析,因此更复杂些,所以处理速 度略慢。 在字符串中引用复杂的变量组合时,可能会产生一些问题,下面的代码会正常工作: echo "value = $foo"; echo "value = $a[$i]"; 而下面的代码却不能得到我们希望的结果: echo "value = $a[$i][$j]"; //我们希望打印二维数组$a的某个元素。 为避免这些字串使用中的潜在问题,我们通常把复杂的变量从字串中分离开来,就像这 样: echo 'value = ' . $a[$i][$j]; 还有一种办法是将复杂变量用花括号括起来,语法分析器就能正确辨认了: echo "value = {$a[$i][$j]}" //打印二维数组$a的某个元素 这样,又出现新问题了。当我们想在字串中引用花括号字符本身时,就要记得使用转义符了: $var = 3; echo "value = {$var}"; // 打印结果 "value = 3" echo "value = \{$var}"; // 打印结果 "value = {3}" 三、斜杠和SQL语句 生成HTML代码或SQL查询语句是编写PHP程序时经常遇到而且是件有趣的事情。为什么这么说呢, 因为这涉及到生成另外一种类型的代码,你必须仔细地考虑和遵循这种代码所要求的编写语法和规 则。 我们来看这样一个例子,假如你想查询数据库中名字是“O'Keefe”的用户,通常SQL语句的形式 是这样的: select * from users where last_name = 'O\'Keefe' 请注意SQL语句这个英文所有格(撇号)需使用反斜杠转义。PHP专门提供了一些函数来处理这样 的情况,函数AddSlashes($str)的用途就是自动在字串中对引号字符插入反斜杠转义符: $last_name = "O'Keefe"; $sql = "select * from users where last_name = '" . addslashes($last_name) . "'"; 在这个例子中,你还要在last_name字串外面括上单引号(SQL语法要求),由于这里使用的是双 引号串,所以对这对单引号就无须使用转义了。下面的这个语句是使用单引号串的等价形式: $sql = 'select * from users where last_name = \'' . addslashes($last_name) . '\''; 任何时候你要在数据库中写入字串,你都必须确保里面的引号正确使用了转义符号,这 是很多PHP 初学者常犯的错误。 四、双引号和HTML 与SQL语句不同,在HTML语言中双引号常被用来表示字串(现在很多浏览器具备较强的容错功 能,允许在HTML中用单引号甚至不用引号表示字符串),例如: $html = ''.$link.''; $html = "$link"; HTML语言不支持反斜杠转义,这一点在我们使用表单的hidden inputs来传输数据的时候就会有所 体会了。设置hidden inputs的值的最好办法,是使用htmlspecialchars()函数来编码。下面的语句可 以正常传输一个可能包含双引号的数据: 经常有人问我,听说在PHP中处理字符串用单引号会快,那么如果存在变量替换的时候,是 简单的回答,显然是苍白无力的。 今天我们来做使用单引号连接快呢,还是双引号快呢, 个实验,看看到底单引号和双引号有什么区别,谁快,谁慢。 测试代码如下: 接下来,让我们以前文章提到过的Opcodes生成器来看看,最终我们的这段代码是怎么被执行的: Branch analysis from position: 0 Return found filename: /home/xinchen/string.php function name: (null) number of ops: 24 compiled vars: !0 = $single_quotes, !1 = $double_quotes, !2 = $var, !3 = $single_quotes_var, !4 = $double_quotes_var, !5 = $single_quotes_var_pre, !6 = $double_quotes_var_pre line # op fetch ext return operands ------------------------------------------------------------------------------- 2 0 ASSIGN !0, 'This+is+a+String' 3 1 ASSIGN !1, 'This+is+a+String' 4 2 ECHO !0 5 3 ECHO !1 7 4 ASSIGN !2, 'String' 8 5 CONCAT ~3 'This+is+a+', !2 6 ASSIGN !3, ~3 9 7 INIT_STRING ~5 8 ADD_STRING ~5 ~5, 'This+is+a+' 9 ADD_VAR ~5 ~5, !2 10 ASSIGN !4, ~5 11 11 ECHO !3 12 12 ECHO !4 14 13 ASSIGN !2, 'This' 16 14 CONCAT ~8 !2, '+is+a+String' 15 ASSIGN !5, ~8 17 16 INIT_STRING ~10 17 ADD_VAR ~10 ~10, !2 18 ADD_STRING ~10 ~10, '+is+a+String' 19 ASSIGN !6, ~10 19 20 ECHO !5 20 21 ECHO !6 22 22 RETURN 1 23* ZEND_HANDLE_EXCEPTION 注意第0到第3条op line, 可以看出在没有使用变量替换的情况下,双引号的和单引号所产生的Opcodes是一样的。 再来看:第4到第12条, 可以发现,在使用变量替换的情况下,使用双引号和单引号所生成的Opcodes是不一样的,我们来分析双引号情况下的Opcodes: 7 INIT_STRING 初始化一个字符串变量,存放在~5临时变量中。 8 ADD_STRING 将第一部分字符串写入。 9 ADD_VAR 将变量替换的字符串写入。 第16-28行同理。 从这里我们可以发现,在使用双引号的情况下和使用单引号的情况下,同样的逻辑,所经历的执行确实不一样的(因为,Opcodes对于PHP来说就是最终的执行代码)。单单从生成的Opcods数量来说,就已经足以证明确实是使用单引号会快了。 至于编译阶段,双引号和单引号的区别也是很大的, 我就举个数字来说明: 在scanning阶段, 对于双引号的词法规则有14条,而对于单引号,仅仅只有6条。 呵呵,是不是经过这样的分析,你会更清楚的了解到以后该怎么使用单引号和双引号了呢, 顺便说一句,对于不需要变量替换的纯字符串,大家都知道,因为在C/C++中,双引号才表示字符串,所以这种情况下,还是使用双引号的好。 另外对于W3C标准来说, HTML中的属性值应该是使用双引号来包含的 ,所以不要习惯了单引号,到处滥用哦 看到这些,我可以想到光光是一个引号问题都有这么大学问,是应该好好学习下免得以后搞得我头痛。 希望大家也要注意下了。 第5章 字符串 我们一直在使用字符串,C#中string关键字的映射实际上指向.NET 基类System.String。System.String是一个功能非常强大且用途非常广泛的基类,但它不是.NET中唯一与字符串相关的类。其他的用来处理字符串的.NET类还有很多,如System.Text 和 System.Text.Regular Expressions命名空间中的类等等。 一、System.String类 System.String是一个类,专门用于存储字符串,允许对字符串进行许多操作。由于这种数据类型非常重要,C#提供了它自己的关键字和相关的语法,以便于使用这个类来处理字符串。 使用运算符重载可以连接字符串: string message1 = "Hello"; //return "Hello" message1 += ", There"; // return "Hello, There " string message2 = message1 + "!"; // return "Hello, There!" C#还允许使用类似于索引器的语法来提取指定的字符: char char4 = message[4]; // returns 'a'. Note the char is zero-indexed 这个类可以完成许多常见的任务,例如替换字符、删除空白和把字母变成大写形式等。可用的方法如表所示。 方 法 作 用 Compare 比较字符串的内容,考虑文化背景(区域),确定某些字符是否相等 CompareOrdinal 与Compare一样,但不考虑文化背景 把多个字符串实例合并为一个实例 Concat 把特定数量的字符从选定的下标复制到数组的一个全新实例中 CopyTo 格式化包含各种值的字符串和如何格式化每个值的说明符 Format 定位字符串中第一次出现某个给定子字符串或字符的位置 IndexOf 定位字符串中第一次出现某个字符或一组字符的位置 IndexOfAny 把一个字符串实例插入到另一个字符串实例的指定索引处 Insert 合并字符串数组,建立一个新字符串 Join LastIndexOf 与IndexOf一样,但定位最后一次出现的位置 LastIndexOfAny 与IndexOfAny,但定位最后一次出现的位置 在字符串的开头,通过添加指定的重复字符填充字符串 PadLeft 在字符串的结尾,通过添加指定的重复字符填充字符串 PadRight 用另一个字符或子字符串替换字符串中给定的字符或子字符串 Replace 在出现给定字符的地方,把字符串拆分为一个子字符串数组 Split 在字符串中获取给定位置的子字符串 Substring 把字符串转换为小写形式 ToLower 把字符串转换为大写形式 ToUpper 删除首尾的空白 Trim 注意:这个表并不完整,但可以让您明白字符串所提供的功能。 1、创建字符串 如上所述,string类是一个功能非常强大的类,它执行许多很有用的方法。但是,string类存在一个问题:重复修改给定的字符串,效率会很低,它实际上是一个不可变的数据类型,一旦对字符串对象进行了初始化,该字符串对象就不能改变了。表面上修改字符串内容的方法和运算符实际上是创建一个新的字符串,如果必要,可以把旧字符串的内容复制到新字符串中。例如,下面的代码: string greetingText = "Hello from all the guys at Wrox Press. "; greetingText += "We do hope you enjoy this book as much as we enjoyed writing it."; 在执行这段代码时,首先,创建一个System.String类型的对象,并初始化为文本“Hello from all the guys at Wrox Press. ”。注意句号后面有一个空格。此时.NET 运行库会为该字符串分配足够的内存来保存这个文 本(39个字符),再设置变量greetingText,表示这个字符串实例。 从语法上看,下一行代码是把更多的文本添加到字符串中。实际上并非如此,而是创建一个新字符串 实例,给它分配足够的内存,以保存合并起来的文本(共103个字符)。最初的文本“Hello from all the people at Wrox Press.”复制到这个新字符串中,再加上额外的文本“We do hope you enjoy this book as much as we enjoyed writing it.”。然后更新存储在变量greetingText中的地址,使变量正确地指向新的字符串对象。旧的 字符串对象被撤销了引用—— 不再有变量引用它,下一次垃圾收集器清理应用程序中所有未使用的对象 时,就会删除它。 这本身还不坏,但假定要对这个字符串加密,在字母表中,用ASCII码中的字符替代其中的每个字母(标 点符号除外),作为非常简单的加密模式的一部分,就会把该字符串变成“Ifmmp gspn bmm uif hvst bu Xspy Qsftt. Xf ep ipqf zpv fokpz uijt cppl bt nvdi bt xf fokpzfe xsjujoh ju.”。完成这个任务有好几种方式,但最简单、 最高效的一种(假定只使用String类)是使用String. Replace()方法,把字符串中指定的子字符串用另一个子 字符串代替。使用Replace(),加密文本的代码如下所示: string greetingText = "Hello from all the guys at Wrox Press. "; greetingText += "We do hope you enjoy this book as much as we enjoyed writing it."; for(int i = 'z'; i>='a' ; i--) { char old1 = (char)i; char new1 = (char)(i+1); greetingText = greetingText.Replace(old1, new1); } for(int i = 'Z'; i>='A' ; i--) { char old1 = (char)i; char new1 = (char)(i+1); greetingText = greetingText.Replace(old1, new1); } Console.WriteLine("Encoded:\n" + greetingText); 注意: Replace()以一种智能化的方式工作,在某种程度上,它并没有创建一个新字符串,除非要对旧字符串 进行某些改变。原来的字符串包含23个不同的小写字母,和3个不同的大写字母。所以Replace()就分配一 个新字符串,共26次,每个新字符串都包含103个字符。因此加密过程需要在堆上有一个能存储总共2678 个字符的字符串对象,最终将等待被垃圾收集~显然,如果使用字符串进行文字处理,应用程序就会有严 重的性能问题。 为了解决这个问题,Microsoft提供了System.Text.StringBuilder类。StringBuilder不像String那样支持 非常多的方法。在StringBuilder上可以进行的处理仅限于替换和添加或删除字符串中的文本。但是,它的 工作方式非常高效。 在使用String类构造一个字符串时,要给它分配足够的内存来保存字符串,但StringBuilder通常分配 的内存会比需要的更多。开发人员可以选择显式指定StringBuilder要分配多少内存,但如果没有显式指定, 存储单元量在默认情况下就根据StringBuilder初始化时的字符串长度来确定。它有两个主要的属性: ? Length指定字符串的实际长度; ? Capacity是字符串占据存储单元的最大长度。 对字符串的修改就在赋予StringBuilder实例的存储单元中进行,这就大大提高了添加子字符串和替换单个字符的效率。删除或插入子字符串仍然效率低下,因为这需要移动随后的字符串。只有执行扩展字符串容量的操作,才需要给字符串分配新内存,才可能移动包含的整个字符串。在添加额外的容量时,从经验来看,StringBuilder如果检测到容量超出,且容量没有设置新值,就会使自己的容量翻倍。 例如,如果使用StringBuilder对象构造最初的欢迎字符串,可以编写下面的代码: StringBuilder greetingBuilder = new StringBuilder("Hello from all the guys at Wrox Press. ", 150); greetingBuilder.AppendFormat("We do hope you enjoy this book as much as we enjoyed writing it"); 注意: 为了使用StringBuilder类,需要在代码中引用System.Text。 在这段代码中,为StringBuilder设置的初始容量是150。最好把容量设置为字符串可能的最大长度,确保StringBuilder不需要重新分配内存,因为其容量足够用了。理论上,可以设置尽可能大的数字,足够给该容量传送一个int,但如果实际上给字符串分配20亿个字符的空间(这是StringBuilder实例允许拥有的最大理论空间),系统就可能会没有足够的内存。 在调用Append()方法时,其他文本就放在空的空间中,不需要分配更多的内存。但是,多次替换文本才能获得使用StringBuilder所带来的性能提高。例如,如果要以前面的方式加密文本,就可以执行整个加密过程,无须分配更多的内存: StringBuilder greetingBuilder = new StringBuilder("Hello from all the guys at Wrox Press. ", 150); greetingBuilder.Append("We do hope you enjoy this book as much as we " + "enjoyed writing it"); Console.WriteLine("Not Encoded:\n" + greetingBuilder); for(int i = 'z'; i>='a' ; i--) { char old1 = (char)i; char new1 = (char)(i+1); greetingBuilder = greetingBuilder.Replace(old1, new1); } for(int i = 'Z'; i>='A' ; i–– ) { char old1 = (char)i; char new1 = (char)(i+1); greetingBuilder = greetingBuilder.Replace(old1, new1); } Console.WriteLine("Encoded:\n" + greetingBuilder); 这段代码使用了StringBuilder.Replace()方法,它的功能与String.Replace()一样,但不需要在过程中复制字符串。在上述代码中,为存储字符串而分配的总存储单元是150个字符,用于StringBuilder实例以及在最后一个Console.WriteLine()语句中执行字符串操作期间分配的内存。 一般,使用StringBuilder可以执行字符串的操作,String可以存储字符串或显示最终结果。 2 StringBuilder成员 前面介绍了StringBuilder的一个构造函数,它的参数是一个初始字符串及该字符串的容量。还有几个其他的StringBuilder构造函数,例如,可以只提供一个字符串: StringBuilder sb = new StringBuilder("Hello"); 或者用给定的容量创建一个空的StringBuilder: StringBuilder sb = new StringBuilder(20); 除了前面介绍的Length 和 Capacity属性外,还有一个只读属性MaxCapacity,它表示对给定的StringBuilder实例的容量限制。在默认情况下,这由int.MaxValue给定(大约20亿,如前所述)。但在构造StringBuilder对象时,也可以把这个值设置为较低的值: // This will both set initial capacity to 100, but the max will be 500. // Hence, this StringBuilder can never grow to more than 500 characters, // otherwise it will raise exception if you try to do that. StringBuilder sb = new StringBuilder(100, 500); 还可以随时显式地设置容量,但如果把这个值设置为低于字符串的当前长度,或者超出了最大容量,就会抛出一个异常: StringBuilder sb = new StringBuilder("Hello"); sb.Capacity = 100; 主要的StringBuilder方法如表所示。 名 称 作 用 给当前字符串添加一个字符串 Append() 添加特定格式的字符串 AppendFormat() 在当前字符串中插入一个子字符串 Insert() 从当前字符串中删除字符 Remove() 在当前字符串中,用某个字符替换另一个字符,或者用当前字符串中Replace() 的一个子字符串替换另一字符串 ToString() 把当前字符串转换为System.String对象(在System.Object中被重写) 其中一些方法还有几种格式的重载方法。 注意: AppendFormat()实际上会在调用Console.WriteLine()时调用,它负责确定所有像{0:D}的格式化表达式应使用什么表达式替代。下一节讨论这个问题。 不能把StringBuilder转换为String(隐式转换和显式转换都不行)。如果要把StringBuilder的内容输出为String,唯一的方式是使用ToString()方法。 前面介绍了StringBuilder类,说明了使用它提高性能的一些方式。注意,这个类并不总能提高性能。StringBuilder类基本上应在处理多个字符串时使用。但如果只是连接两个字符串,使用System.String会比较好。 3、格式化字符串 前面的代码示例中编写了许多类和结构,对这些类和结构执行ToString()方法,都是为了显示给定变量的内容。但是,用户常常希望以各种可能的方式显示变量的内容,在不同的文化或地区背景中有不同的格式。.NET基类System.DateTime就是最明显的一个示例:可以把日期显示为10 June 2008、10 Jun 2008、6/10/08 (美国)、10/6/08 (英国)或10.06.2008 (德国)。 同样,第6章中编写的Vector结构执行Vector.ToString()方法,是为了以(4, 56, 8)格式显示矢量。编写矢量的另一个非常常用的方式是4i + 56j + 8k。如果要使类的用户友好性比较高,就需要使用某些工具以用户希望的方式显示它们的字符串表示。.NET运行库定义了一种标准方式:使用接口IFormattable,本节的主题就是说明如何把这个重要特性添加到类和结构上。 在显示一个变量时,常常需要指定它的格式,此时我们经常调用Console.WriteLine()方法。因此,我们把这个方法作为示例,但这里的讨论适用于格式化字符串的大多数情况。例如,如果要在列表框或文本框中显示一个变量的值,一般要使用String.Format()方法来获得该变量的合适字符串表示,但用于请求所需格 式的格式说明符与传递给Console.WriteLine()的格式相同,因此本节把Console.WriteLine()作为一个示例来说明。首先看看在为基本类型提供格式字符串时会发生什么,再看看如何把自己的类和结构的格式说明符添加到过程中。 以前在Console.Write()和Console.WriteLine()中使用了格式字符串: double d = 13.45; int i = 45; Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i); 格式字符串本身大都由要显示的文本组成,但只要有要格式化的变量,它在参数列表中的下标就必须放在括号中。在括号中还可以有与该项的格式相关的其他信息,例如可以包含: ? 该项的字符串表示要占用的字符数,这个信息的前面应有一个逗号,负值表示该项应左对齐,正值表示该项应右对齐。如果该项占用的字符数比给定的多,其内容也会完整地显示出来。 ? 格式说明符也可以显示出来。它的前面应有一个冒号,表示应如何格式化该项。例如,把一个数字格式化为货币,或者以科学计数法显示。 数字类型的常见格式说明符: 格 式 应 用 含 义 示 例 符 数字类型 专用场合的货币值 C $4834.50 (USA) ?4834.50 (UK) 只用于整数一般的整数 D 4834 类型 数字类型 科学计数法 E 4.834E+003 数字类型 小数点后的位数固定 F 4384.50 数字类型 一般的数字 G 4384.5 数字类型 通常是专用场合的数字N 4,384.50 (UK/USA) 格式 4 384,50 (欧洲大陆) 数字类型 百分比计数法 P 432,000.00% 只用于整数十六进制格式 X 1120 (如果要显示 类型 0x1120,需要写上0x) 如果要在整数上加上前导0,可以将格式说明符0重复所需的次数。例如,格式说明符0000会把3显示为0003,99显示为0099。 这里不能给出完整的列表,因为其他数据类型有自己的格式说明符。本节的主要目的是说明如何为自己的类定义格式说明符。 1. 字符串的格式化 为了说明如何格式化字符串,看看执行下面的语句会得到什么结果: Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i); Console.WriteLine()只是把参数的完整列表传送给静态方法String.Format(),如果要在字符串中以其他方式格式化这些值,例如显示在一个文本框中,也可以调用这个方法。带有3个参数的WriteLine()重载方法如下: // Likely implementation of Console.WriteLine() public void WriteLine(string format, object arg0, object arg1) { Console.WriteLine(string.Format(format, arg0, arg1)); } 上面的代码依次调用了带有1个参数的重载方法WriteLine(),仅显示了传递过来的字符串的内容,没 有对它进行进一步的格式化。 String.Format()现在需要用对应对象的合适字符串表示来替换每个格式说明符,构造最终的字符串。但是,如前所述,对于这个建立字符串的过程,需要StringBuilder实例,而不是String实例。在这个示例中,StringBuilder实例是用字符串的第一部分(即文本“The double is”)创建和初始化的。然后调用StringBuilder.AppendFormat()方法,传递第一个格式说明符“{0,10:E}”和相应的对象double,把这个对象的字符串表示添加到构造好的字符串中,这个过程会继续重复调用StringBuilder.Append()和StringBuilder.AppendFormat()方法,直到得到了全部格式化好的字符串为止。 下面的内容比较有趣。StringBuilder.AppendFormat()需要指出如何格式化对象,它首先检查对象,确定它是否执行System命名空间中的接口IFormattable。只要试着把这个对象转换为接口,看看转换是否成功即可,或者使用C#关键字is,也能实现此测试。如果测试失败,AppendFormat()只会调用对象的ToString()方法,所有的对象都从System.Object继承了这个方法或重写了该方法。在前面给出的编写各种类和结构的示例中,执行过程都是这样,因为我们编写的类都没有执行这个接口。这就是在前面的章节中,Object.ToString()的重写方法允许在Console.WriteLine()语句中显示类和结构如Vector的原因。 但是,所有预定义的基本数字类型都执行这个接口,对于这些类型,特别是这个示例中的double和int,就不会调用继承自System.Object的基本ToString()方法。为了理解这个过程,需要了解IFormattable接口。 IFormattable只定义了一个方法,该方法也叫作ToString(),它带有两个参数,这与System. Object版本的ToString()不同,它不带参数。下面是IFormattable的定义: interface IFormattable { string ToString(string format, IFormatProvider formatProvider); } 这个ToString()重载方法的第一个参数是一个字符串,它指定要求的格式。换言之,它是字符串的说明符部分,放在字符串的{}中,该参数最初传递给Console.WriteLine()或String. Format()。例如,在本例中,最初的语句如下: Console.WriteLine("The double is {0,10:E} and the int contains {1}", d, i); 在计算第一个说明符{0,10:E}时,在double变量d上调用这个重载方法,传递给它的第一个参数是E。StringBuilder.AppendFormat()传递的总是显示在原始字符串的合适格式说明符内冒号后面的文本。 本书不讨论ToString()的第2个参数,它是执行接口IFormatProvider的对象引用。这个接口提供了ToString()在格式化对象时需要考虑的更多信息—— 一般包括文化背景信息(.NET文化背景类似于Windows时区,如果格式化货币或日期,就需要这些信息)。如果直接从源代码中调用这个ToString()重载方法,就需要提供这样一个对象。但StringBuilder. Append Format()为这个参数传递一个空值。如果formatProvider为空,ToString()就要使用系统设置中指定的文化背景信息。 现在回过头来看看本例。第一个要格式化的项是double,对此要求使用指数计数法,格式说明符为E。如前所述,StringBuilder.AppendFormat()方法会建立执行IFormattable接口的对象double,因此要调用带有两个参数的ToString()重载方法,其第一个参数是字符串“E”,第二个参数为空。现在double的这个方法在执行时,会考虑要求的格式和当前的文化背景,以合适的格式返回double的字符串表示。StringBuilder.AppendFormat()则按照需要在返回的字符串中添加前导空格,使之共有10个字符。 下一个要格式化的对象是int,它不需要任何特殊的格式 (格式说明符是{1})。由于没有格式要求,StringBuilder.AppendFormat()会给该格式字符串传递一个空引用,并适当地响应带有两个参数的int.ToString()重载方法。由于没有特殊的格式要求,所以也可以调用不带参数的ToString()方法。
/
本文档为【【2017年整理】php单引号和双引号的区别】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索