1.内部使用 C 的 longjmp 机制让出一个协程。 因此,如果一个 C 函数 foo 调用了一个 API 函数, 而这个 API 函数让出了(直接或间接调用了让出函数)。 由于 longjmp 会移除 C 栈的栈帧, Lua 就无法返回到 foo 里了。
2.为了回避这类问题, 碰到 API 调用中调用让出时,除了那些抛出错误的 API 外,还提供了三个函数: lua_yieldk, lua_callk,和 lua_pcallk 。 它们在让出发生时,可以从传入的 延续函数 (名为 k 的参数)继续运行。
3.我们需要预设一些术语来解释延续点。 对于从 Lua 中调用的 C 函数,我们称之为 原函数。 从这个原函数中调用的上面所述的三个 C API 函数我们称之为 被调函数。 被调函数可以使当前线程让出。 (让出发生在被调函数是 lua_yieldk, 或传入 lua_callk 或 lua_pcallk 的函数调用了让出时。)
4.假设正在运行的线程在执行被调函数时让出。 当再次延续这条线程,它希望继续被调函数的运行。 然而,被调函数不可能返回到原函数中。 这是因为之前的让出 *** 作破坏了 C 栈的栈帧。 作为替代品,Lua 调用那个作为被调函数参数给出的 延续函数 。 正如其名,延续函数将延续原函数的任务。
5.注意这里那个额外的显式的对延续函数的调用:Lua 仅在需要时,这可能是由错误导致的也可能是发生了让出而需要继续运行,才会调用延续函数。 如果没有发生过任何让出,调用的函数正常返回, 那么 lua_pcallk (以及 lua_callk)也会正常返回。 (当然,这个例子中你也可以不在之后调用延续函数, 而是在原函数的调用后直接写上需要做的工作。)
6.Lua 会把延续函数看作原函数。 延续函数将接收到和原函数相同的 Lua 栈,其接收到的 lua 状态也和 被调函数若返回后应该有的状态一致。 (例如, lua_callk 调用之后, 栈中之前压入的函数和调用参数都被调用产生的返回值所替代。) 这时也有相同的上值。 等到它返回的时候,Lua 会将其看待成原函数的返回去 *** 作。
7.我们需要预设一些术语来解释延续点。 对于从 Lua 中调用的 C 函数,我们称之为 原函数。 从这个原函数中调用的上面所述的三个 C API 函数我们称之为 被调函数。 被调函数可以使当前线程让出。 (让出发生在被调函数是 lua_yieldk, 或传入 lua_callk 或 lua_pcallk 的函数调用了让出时。)
8.假设正在运行的线程在执行被调函数时让出。 当再次延续这条线程,它希望继续被调函数的运行。 然而,被调函数不可能返回到原函数中。 这是因为之前的让出 *** 作破坏了 C 栈的栈帧。 作为替代品,Lua 调用那个作为被调函数参数给出的 延续函数 。 正如其名,延续函数将延续原函数的任务。
希望能帮到你,谢谢!
import java.util.Random
import java.util.Scanner
public class T {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(System.in)
int difficulty//难度
int mode//运算类型
int answer//答案
int amount//挑战题目数量
int score = 0//得分
System.out.println("请输入难度(1:一位数、2:两位数、3:三位数):")
difficulty = in.nextInt()
System.out.println("请输入运算类型(1:加、2:减、3:乘、4:除):")
mode = in.nextInt()
System.out.println("请输入想要挑战的题目数量:")
amount = in.nextInt()
Random random = new Random()
for (int i = 0i <amounti++) {
if (difficulty == 1) {
if (mode == 1) {
int x = random.nextInt(10)
int y = random.nextInt(10)
System.out.println("第" + i + "题:")
System.out.print(x + " + " + y + " = ")
answer = in.nextInt()
if (answer == (x + y)) {
System.out.println("答对了\n")
score++
} else {
System.out.println("答错了,答案是:" + (x + y) + "\n")
}
} else if (mode == 2) {
int x = random.nextInt(10)
int y = random.nextInt(10)
System.out.println("第" + i + "题:")
System.out.print(x + " - " + y + " = ")
answer = in.nextInt()
if (answer == (x - y)) {
System.out.println("答对了\n")
score++
} else {
System.out.println("答错了,答案是:" + (x - y) + "\n")
}
} else if (mode == 3) {//乘法
} else if (mode == 4) {//除法 考虑小数的问题
} else {
throw new Exception("运算类型输入值不合法")
}
} else if (difficulty == 2) {
if (mode == 1) {
int x = random.nextInt(100)
int y = random.nextInt(100)
System.out.println("第" + i + "题:")
System.out.print(x + " + " + y + " = ")
answer = in.nextInt()
if (answer == (x + y)) {
System.out.println("答对了\n")
score++
} else {
System.out.println("答错了,答案是:" + (x + y) + "\n")
}
} else if (mode == 2) {
} else if (mode == 3) {//乘法
} else if (mode == 4) {//除法 考虑小数的问题
} else {
throw new Exception("运算类型输入值不合法")
}
} else if (difficulty == 3) {
if (mode == 1) {
int x = random.nextInt(1000)
int y = random.nextInt(1000)
System.out.println("第" + i + "题:")
System.out.print(x + " + " + y + " = ")
answer = in.nextInt()
if (answer == (x + y)) {
System.out.println("答对了\n")
score++
} else {
System.out.println("答错了,答案是:" + (x + y) + "\n")
}
} else if (mode == 2) {
} else if (mode == 3) {//乘法
} else if (mode == 4) {//除法 考虑小数的问题
} else {
throw new Exception("运算类型输入值不合法")
}
} else {
throw new Exception("难度输入值不合法")
}
}
System.out.println("挑战结束,您的分数为:" + score)
}
}
我就只举了加法的例子,其他运算的写法都是类似的,你照葫芦画瓢即可
运行结果:
public class FooDemo{ //定义Java类,公用,类名为FooDemostatic boolean foo(char c) { //定义静态方法foo,返回值布尔型,参数为字符型c
System.out.print(c)//向标准输出设备输出字符c
return true//返回true
}
public static void main(String[] args ) {//定义java程序入口
int i =0//初始化整型变量i 初始值为0
for ( foo('a')foo('b')&&(i<2)foo('c')){ //循环,初始化表达式为foo('a'),此时控制台输出a,
// 然后开始判断条件表达式,foo('b')&&(i<2), 第一步的时候i=0,控制台上先输出b,然后表达式相当于true&&(0<2)=true,执行循环体
// 此时控制台上的字符是 abd
// 第二次循环 此时不运行初始化表达式,但运行增量表达式,控制台输出c, 此时控制台上变为 abdc
// 继续判断条件表达式,foo('b')&&(i<2), 第一步的时候i=1,控制台上先输出b,然后表达式相当于true&&(1<2)=true,执行循环体
// 此时控制台上的字符是 abdcbd
// 然后运行增量表达式,控制台输出c,控制台变为 abdcbdc
// 继续判断条件表达式,foo('b')&&(i<2), 第一步的时候i=2,控制台上先输出b,然后表达式相当于true&&(3<2)=false,不执行循环体
// 此时控制台上的字符是 abdcbdcb
i++ //i自增1
foo('d')//调用方法,控制台输出d
}
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)