假设我有
#define DETUNE1 sqrt(7)-sqrt(5)
#define DETUNE2 sqrt(11)-sqrt(7)
我在我的程序中多次调用它们。
DETUNE1和DETUNE2是否计算每时间?
答案 0 :(得分:6)
每次调用时是否计算出DETUNE1和DETUNE2?
非常不可能。
因为您使用常量调用sqrt
,所以大多数编译器会优化对sqrt
函数的调用,并将其替换为常量值。海湾合作委员会在-O1
处这样做。铿锵声。 (See live)。
在一般情况下,如果您有一个n
为运行时值的宏:
#define DETUNE1(n) (sqrt(n)-sqrt(n))
然后在文本替换后,至少需要计算其中一个sqrt
函数。
请注意,您的宏不是安全的。你应该有它周围的括号是安全的。例如,由于DETUNE1 * DETUNE1
不会产生您期望的结果。
答案 1 :(得分:3)
是每次都会计算出来。最好是#define
计算出的值。您还需要确保将它们放在括号中,因为它可能会产生意外结果。
e.g。如果您在计算中使用如下:
int result = DETUNE1 * 4
然后它将导致
int result = sqrt(7)-sqrt(5) * 4
因此,乘法将在减法之前完成,因为operator precedence in C
答案 2 :(得分:2)
#define文本替换你的宏声明,所以每次你写:DETUNE1,sqrt(7)-sqrt(5)代替它。所以如果你多次写DETUNE1多次评估将会完成。
答案 3 :(得分:1)
是的,#define只是用您定义的内容替换短语的每个实例
当编译器编译程序时,在进行任何插入之前,会有一个称为预处理的阶段。在这个阶段,编译器会盲目地用它们的定义替换所有#define实例,因此代码中使用DETUNE1的每个地方都将被sqrt(7)-sqrt(5)替换,这是一个当然的计算
您可以使用变量预先缓存此值,或者更好 - 自己计算并将其存储在如下定义中:
public class LogWriter implements Runnable {
InputStreamReader in;
DataOutputStream out;
public LogWriter(InputStreamReader in, DataOutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
try {
File file = new File("logs.txt");
// creates the file
if (!file.exists()) {
System.out.println("Creating File");
file.createNewFile();
}
String inputLine = null;
BufferedReader input = new BufferedReader(in);
System.out.println("Writing data....");
while ((inputLine = input.readLine()) != null) {
//System.out.println("Test");
System.out.println("Sending Acknowledgement....");
out.writeUTF("Upload successful");
out.writeUTF("Ok");
FileWriter fstream = new FileWriter(file, true);
BufferedWriter fbw = new BufferedWriter(fstream);
fbw.write(inputLine);
fbw.newLine();
fbw.flush();
fbw.close();
}
//DataOutputStream out =
//new DataOutputStream(server.getOutputStream());
//out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");
//server.close();
} catch (IOException ex) {
Logger.getLogger(LogWriter.class.getName()).log(Level.SEVERE, null, ex);
ex.printStackTrace();
}
}
}
所以
sqrt(7)-sqrt(5) = 0.409
这是最有效的方法 - 完全避免计算。
中C宏的更多信息,请参见此处答案 4 :(得分:0)
是的 - 还有另一个避免宏的原因(好像我们还需要它)。请改用const
:
const double DETUNE1 = sqrt(7) - sqrt(5);
const double DETUNE2 = sqrt(11) - sqrt(7);