在这里,我们将给大家分享关于编译器的行为与通用方法的null参数不同的知识,让您更了解编译器常用语法分析方法的本质,同时也会涉及到如何更有效地不起作用\给出了错误的输出为什么putchar()在wh
在这里,我们将给大家分享关于编译器的行为与通用方法的null参数不同的知识,让您更了解编译器常用语法分析方法的本质,同时也会涉及到如何更有效地 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?、AngularJS then()的行为与success()不同 – error()、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、arm三大编译器的不同选择编译的内容。
本文目录一览:- 编译器的行为与通用方法的null参数不同(编译器常用语法分析方法)
- 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?
- AngularJS then()的行为与success()不同 – error()
- arm-linux-gcc 常用参数讲解 gcc编译器使用方法
- arm三大编译器的不同选择编译
编译器的行为与通用方法的null参数不同(编译器常用语法分析方法)
以下代码可以在Eclipse上完美编译,但是无法通过javac进行编译:
public class HowBizarre { public static <P extends Number, T extends P> void doIt(P value) { } public static void main(String[] args) { doIt(null); }}
我简化了代码,所以现在根本不使用T。不过,我看不出发生此错误的原因。由于某种原因,javac决定T代表Object,然后抱怨Object不符合T的界限(这是对的):
HowBizarre.java:6:不兼容的类型;推断的类型实参java.lang.Number,java.lang.Object不符合类型变量P,T的范围
发现:
<P,T>
无效必需:无效
doIt(null); ^
请注意,如果我将null参数替换为非null值,则可以正常编译。
哪个编译器行为正确,为什么?这是其中之一的错误吗?
答案1
小编典典该问题是由于JLS规范所致,该规范要求必须将不可推论的类型参数推导为Object
,即使它不满足界限(并因此会触发编译错误)。
以下是“错误”报告的摘录(为清楚起见,已对其进行了进一步注释):
[“错误” ID 6299211-方法类型变量:推断为空
](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6299211)
该程序无法编译:
public class Try { void m() { java.util.Collections.max(null); }}
状态 :已 关闭,不是缺陷。
评估 : 这不是错误
。推理算法无法从参数(null
)收集任何信息,并且不会在对返回值有任何期望的地方调用该方法。在这种情况下,编译器必须推断出java.lang.Object
类型变量。JLS
15.12.2.8推断未解决的类型参数然后,还可以推断出尚未推断出的所有剩余类型变量
Object
但是,
Object
不是的子类型,Comparable<? superObject>
因此不在声明的类型变量的范围内Collections.max
:
<T extends
Object& Comparable<? super T>
> T max(Collection<?extendsT>)
进一步的探索
使用显式类型参数可以“解决”问题:
HowBizarre.<Number,Integer>doIt(null); // compiles fine in javac
为了表明与null
参数无关,而与类型推断的绝对缺乏信息更多,可以尝试例如以下两种声明之一:
<T,U extends Comparable<T>> void doIt()<T extends Number,U extends T> void doIt()
在这两种情况下,调用doIt();
都不会在中进行编译javac
,因为它必须推断U
为符合Object
15.12.2.8,即使这样做会触发编译错误。
关于Eclipse的注意
尽管以上代码片段均未在的某些版本中进行编译javac
,但它们都在Eclipse的某些版本中进行了编译。这可能暗示了Eclipse的错误。众所周知,不同的编译器之间存在分歧。
不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?
如何解决\b 不起作用 \\ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同??
1-10。编写一个程序将其输入复制到其输出,用 \t 替换每个制表符,每个制表符 \b 退格,每个反斜杠 \。这使得制表符和退格在 明确的方式。
我试着写了几次。这是我想出来的。
#include <stdio.h>
main()
{
int i ;
while ((i = getchar())!= EOF){
if (i == ''\t''){
putchar(''\\'');
putchar(''t'');
}
if (i == ''\b''){
putchar(''\\'');
putchar(''b'');
}
if (i == ''\\''){
//putchar(''\\'');
putchar(''\\'');
}
if (i != ''\t''){
putchar(i);
}
}
}
你一定注意到我已经注释掉了第三个 if 子句中的 putchar。 我有三个问题。
-
''\b'' 字符根本不起作用。我找不到任何打印出“\b”的可能性。如何 去做吗?
-
第三个 if 子句中的 putchar 打印三倍的反斜杠。当被注释掉时, 它打印 2 次(根据问题的需要)。为什么..?
-
在第 4 个 if 子句中,putchar 工作正常。但是一旦我从 if 子句中取出它 将其打印到 While Scope(这是我的第一次尝试)。 它打印出 ''\t'' 加上实际的制表符空间然后在下一个字符之后??
为什么会这样..?是什么原因..?
//if (i != ''\t''){
putchar(i); -> this is inside the while scope.
//}
output:
test*tab*this. (executing getchar)
test\t this (executing putchar)
PS - 我不能使用 else 子句。或上述以外的任何内容。我还没有达到 else 或在书中继续。因此,我故意避免使用 else。
解决方法
没有 else
或 continue
,使用辅助变量
#include <stdio.h>
int main(void) {
int i;
while ((i = getchar()) != EOF) {
int processed = 0;
if (i == ''\t'') {
putchar(''\\'');
putchar(''t'');
processed = 1;
}
if (i == ''\b'') {
putchar(''\\'');
putchar(''b'');
processed = 1;
}
if (i == ''\\'') {
putchar(''\\'');
putchar(''\\'');
processed = 1;
}
if (!processed) putchar(i);
}
return 0;
}
$ echo -e ''backslash [\\]\ntab [\t]\nback [\b]'' backslash [\] tab [ ] back ] $ echo -e ''backslash [\\]\ntab [\t]\nback [\b]'' | ./a.out backslash [\\] tab [\t] back [\b]
AngularJS then()的行为与success()不同 – error()
由于在AngularJS中不推荐使用success()和error()函数,我正在更新我的代码,用then()替换它们.现在根据我的理解,这两段代码的行为应该相同:
$http .get(/* some params */) .success(function() { // success cases here }) .error(function() { // error cases here });
和
$http .get(/* some params */) .then(function() { // success cases here },function() { // error cases here });
但在某些情况下,我会得到不同的行为.你能否向我解释为什么会发生这种情况,更重要的是,使用then()函数保证相同行为的方法是什么?
因此它们不适合链接.
var httpPromise = $http .get(/* some params */) .success(function onSuccess(data,status,headers,config) { var modifiedData = doModify(data); //return value ignored return modifiedData; }) .error(function onError(data,config) { // error cases here }); httpPromise.then(function onFullfilled(response) { //chained data lost //instead there is a response object console.log(response.data); //original data console.log(response.status); //original status });
另一方面,.then和.catch方法返回一个派生的promise,适用于从返回(或抛出)值或新promise中链接.
var derivedPromise = $http .get(/* some params */) .then(function onFulfilled(response) { console.log(response.data); //original data console.log(response.status); //original status var modifiedData = doModify(response.data); //return a value for chaining return modifiedData; }) .catch(function onRejected(response) { // error cases here }); derivedPromise.then(function onFullfilled(modifiedData) { //data from chaining console.log(modifiedData); });
响应对象与四个参数
另请注意,$http服务在调用提供给.success和.error方法的函数时提供了四个参数(data,config).
$q服务仅为提供给.then或.catch方法的函数提供一个参数(响应).对于由$http服务创建的promises,响应对象具有以下属性:1
> data – {string | Object} – 使用转换函数转换的响应体.
> status – {number} – 响应的HTTP状态代码.
> headers – {function([headerName])} – 标头getter函数.
> config – {Object} – 用于生成请求的配置对象.
> statusText – {string} – 响应的HTTP状态文本.
Chaining promises
Because calling the
then
method of a promise returns a new derived promise,it is easily possible to create a chain of promises. It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further),it is possible to pause/defer resolution of the promises at any point in the chain. This makes it possible to implement powerful APIs.07001
更新
.enccess和.error方法已被弃用并从AngularJS V1.6中删除.
有关更多信息,请参阅
> Why are angular $http success/error methods deprecated? Removed from v1.6?
arm-linux-gcc 常用参数讲解 gcc编译器使用方法
arm-linux-gcc 常用参数讲解 gcc编译器使用方法
在此之前首先介绍下编译器的工作过程,在 使用GCC编译程序时,编译过程分为四个阶段:
1. 预处理(Pre-Processing)
2. 编译(Compiling)
3. 汇编(Assembling)
4. 链接(Linking)
Linux程序员可以根据自己的需要让 GCC在编译的任何阶段结束,以便检查或 使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为 今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。
以文件example.c为例说明它的用法
0. arm-linux-gcc -o example example.c
不加-c、-S、-E参数,编译器将执行预处理、编译、汇编、连接操作直接生成可执行代码。
-o参数用于指定输出的文件,输出文件名为example,如果不指定输出文件,则默认输出a.out
1. arm-linux-gcc -c -o example.o example.c
-c参数将对源程序example.c进行预处理、编译、汇编操作,生成example.o文件
去掉指定输出选项"-o example.o"自动输出为example.o,所以说在这里-o加不加都可以
2.arm-linux-gcc -S -o example.s example.c
-S参数将对源程序example.c进行预处理、编译,生成example.s文件
-o选项同上
3.arm-linux-gcc -E -o example.i example.c
-E参数将对源程序example.c进行预处理,生成example.i文件(不同版本不一样,有的将预处理后的内容打印到屏幕上)
就是将#include,#define等进行文件插入及宏扩展等操作。
4.arm-linux-gcc -v -o example example.c
加上-v参数,显示编译时的详细信息,编译器的版本,编译过程等。
5.arm-linux-gcc -g -o example example.c
-g选项,加入GDB能够使用的调试信息,使用GDB调试时比较方便。
6.arm-linux-gcc -Wall -o example example.c
-Wall选项打开了所有需要注意的警告信息,像在声明之前就使用的函数,声明后却没有使用的变量等。
7.arm-linux-gcc -Ox -o example example.c
-Ox使用优化选项,X的值为空、0、1、2、3
0为不优化,优化的目的是减少代码空间和提高执行效率等,但相应的编译过程时间将较长并占用较大的内存空间。
8.arm-linux-gcc -I /home/include -o example example.c
-Idirname: 将dirname所指出的目录加入到程序头文件目录列表中。如果在预设系统及当前目录中没有找到需要的文件,就到指定的dirname目录中去寻找。
9.arm-linux-gcc -L /home/lib -o example example.c
-Ldirname:将dirname所指出的目录加入到库文件的目录列表中。在默认状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的库文件,这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后再到系统预设路径中寻找。
10.arm-linux-gcc –static -o libexample.a example.c
静态链接库文件
gcc在命令行上经常使用的几个选项是:
-c 只预处理、编译和汇编源程序,不进行连接。编译器对每一个源程序产生一个目标文件。
-o file 确定输出文件为file。如果没有用-o选项,缺省的可执行文件的输出是a.out,目标文件和汇编文件的输出对source.suffix分别是source.o和source.s,预处理的C源程序的输出是标准输出stdout。
-Dmacro 或-Dmacro=defn 其作用类似于源程序里的#define。例如:% gcc -c -DHAVE_GDBM -DHELP_FILE=\"help\" cdict.c其中第一个- D选项定义宏HAVE_GDBM,在程序里可以用#ifdef去检查它是否被设置。第二个-D选项将宏HELP_FILE定义为字符串“help”(由于 反斜线的作用,引号实际上已成为该宏定义的一部分),这对于控制程序打开哪个文件是很有用的。
-Umacro 某些宏是被编译程序自动定义的。这些宏通常可以指定在其中进行编译的计算机系统类型的符号,用户可以在编译某程序时加上 -v选项以查看gcc缺省定义了哪些宏。如果用户想取消其中某个宏定义,用-Umacro选项,这相当于把#undef macro放在要编译的源文件的开头。
-Idir 将dir目录加到搜寻头文件的目录列表中去,并优先于在gcc缺省的搜索目录。在有多个-I选项的情况下,按命令行上-I选项的前后顺序搜索。dir可使用相对路径,如-I../inc等。
-O 对程序编译进行优化,编译程序试图减少被编译程序的长度和执行时间,但其编译速度比不做优化慢,而且要求较多的内存。
-O2 允许比-O更好的优化,编译速度较慢,但结果程序的执行速度较快。
-g 产生一张用于调试和排错的扩展符号表。-g选项使程序可以用GNU的调试程序GDB进行调试。优化和调试通常不兼容,同时使用-g和-O(-O2)选项经常会使程序产生奇怪的运行结果。所以不要同时使用-g和-O(-O2)选项。
-fpic或-fPIC 产生位置无关的目标代码,可用于构造共享函数库。
以 上是gcc的编译选项。gcc的命令行上还可以使用连接选项。事实上,gcc将所有不能识别的选项传递给连接程序ld。连接程序ld将几个目标文件和库程 序组合成一个可执行文件,它要解决对外部变量、外部过程、库程序等的引用。但我们永远不必要显式地调用ld。利用gcc命令去连接各个文件是很简单的,即 使在命令行里没有列出库程序,gcc也能保证某些库程序以正确的次序出现。
gcc的常用连接选项有下列几个:
-Ldir 将dir目录加到搜寻-l选项指定的函数库文件的目录列表中去,并优先于gcc缺省的搜索目录。在有多个-L选项的情况下,按命令行上-L选项的前后顺序搜索。dir可使用相对路径。如-L../lib等。
-lname 在连接时使用函数库libname.a,连接程序在-Ldir选项指定的目录下和/lib,/usr/lib目录下寻找该库文件。在没有使用-static选项时,如果发现共享函数库libname.so,则使用libname.so进行动态连接。
-static 禁止与共享函数库连接。
-shared 尽量与共享函数库连接
arm三大编译器的不同选择编译
ARM 系列目前支持三大主流的工具链,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compiler Collection (gcc).
关于编译器的行为与通用方法的null参数不同和编译器常用语法分析方法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于 不起作用 \ 给出了错误的输出为什么 putchar() 在 while 范围内的行为与在 if 子句中的行为不同?、AngularJS then()的行为与success()不同 – error()、arm-linux-gcc 常用参数讲解 gcc编译器使用方法、arm三大编译器的不同选择编译的相关知识,请在本站寻找。
本文标签: