我想在 c ++
中使用 printf 打印一个简单的行 int t0 = time(NULL);
int outIndx = 99736;
printf ("time using recurision = %d secs, the result is = %d\n",(time(NULL) - t0), outIndx);
在这种情况下,printf的输出为:
使用recurision的时间= 0秒,结果是= 0
但是当逆转 outIndx 和(时间(NULL) - t0)的顺序时:
printf ("time using recurision = %d secs, the result is = %d\n", outIndx,(time(NULL) - t0));
正确打印printf的输出:
时间使用recurision = 99736秒,结果是= 0
为什么会这样?
答案 0 :(得分:2)
time
会返回time_t
,其大小不必与int
相同。在这种情况下,%d
不是输出的正确格式。
答案 1 :(得分:1)
所以,回答原来的问题。 “printf对参数的顺序是否敏感?”
函数的参数未在标准中定义的顺序,并由编译器使用的调用约定确定。让我们假设您正在使用cdecl调用约定(许多C编译器用于x86体系结构)使用函数中的哪些参数从从右到左进行评估。
让我们举个例子
route.php
这是因为参数是从左到右进行评估的。
但是,在您的示例中,您尝试打印时间类型为“time_t”的ID,如下所示:
int i=5;
printf("%d%d%d%d%d%d",i++,i--,++i,--i,i);
Output :45545
time_t数据类型是为存储系统时间值而定义的ISO C库中的数据类型。这些值从标准time()库函数返回。此类型是标准头中定义的typedef。 ISO C将time_t定义为算术类型,但未指定任何特定类型,范围,分辨率或编码。同样未指明应用于时间值的算术运算的含义。
它取决于下划线体系结构是否以整数形式实现。就您的示例而言,我认为它没有实现为“unsigned int”atleast(int t0),因此结果是实现定义的
答案 2 :(得分:1)
通常,显示time_t
值的方法是使用struct tm
或gmtime()
将其组件细分为localtime()
并显示或转换为strftime()
需要使用ctime()
或difftime()
直接从time_t
转到显示当地时间的字符串。
如果您想出于某种目的看原始值,C标准指定time_t
是实数,这意味着它是整数或浮点数(C 2011(N1570)6.2.5 17)。因此,您应该使用Demo将时间差转换为double:
#include <ctime>
#include <cstdio>
void process()
{
static unsigned dummy = 0;
for (size_t i = 0 ; i < 1000000000 ; ++i)
{
dummy += (dummy + i) / (dummy * i + 1);
}
}
int main()
{
const time_t t0 = time(NULL);
process(); // let say it can take up to a few hours
const time_t t_end = time(NULL);
struct tm breakdown_time = { 0 };
breakdown_time.tm_sec = difftime(t_end, t0);
(void) mktime(&breakdown_time);
printf("duration: %.2d:%.2d:%.2d\n", breakdown_time.tm_hour, breakdown_time.tm_min, breakdown_time.tm_sec);
// Output: "duration: 00:00:08"
}
但是你还没有使用C ++吗? Demo提供了一种计算CPU持续时间的方法(CPU花费的时间,而不是计算在其他线程上花费的时间):
#include <iostream>
#include <iomanip>
void process()
{
static unsigned dummy = 0;
for (size_t i = 0 ; i < 1000000000 ; ++i)
{
dummy += (dummy + i) / (dummy * i + 1);
}
}
int main() {
const std::clock_t t0 = std::clock();
process(); // business code that take time to run
const std::clock_t t_end = std::clock();
const double duration = static_cast<double>(t_end - t0) / CLOCKS_PER_SEC;
std::cout << "duration: " << std::setprecision(3) << duration << " s" << std::endl;
// Output: "duration: 8.92 s"
}
我偶然发现了一种优雅,多功能的计算实际持续时间的方法,它在C ++ 14中使用Demo中的所有高级工具:
#include <iostream>
#include <iomanip>
#include <chrono>
void process()
{
static unsigned dummy = 0;
for (size_t i = 0 ; i < 100000000 ; ++i)
{
dummy += (dummy + i) / (dummy * i + 1);
}
}
template<typename TimeT = std::chrono::milliseconds>
struct measure
{
template<typename F, typename ...Args>
static typename TimeT::rep execution(F&& func, Args&&... args)
{
auto start = std::chrono::system_clock::now();
std::forward<decltype(func)>(func)(std::forward<Args>(args)...);
auto duration = std::chrono::duration_cast< TimeT>
(std::chrono::system_clock::now() - start);
return duration.count();
}
};
int main() {
std::cout << "duration: " << measure<>::execution(process) << " ms" << std::endl;
// Output: "duration: 707 ms"
}
{{3}}
答案 3 :(得分:1)
传递给printf(变量参数函数)的所有参数在调用时被推送到堆栈。 printf例程根据第一个参数中提供的%
标识符串行弹出参数。取决于堆栈上的参数的机器和编译器顺序(从上到下或从下到上)可能会有所不同。
在您的情况下,当您首先传递(time(NULL) - t0)
时,因为它的类型为time_t,并且其大小与printf解释相同,只需看%d
。它会产生问题。
现在为什么当你将(time(NULL) - t0
}作为第二个参数传递时它起作用:
同样的逻辑,假设你的情况下的timt_t是8个字节,其中int是4个字节。对于每个%d
,printf将从参数堆栈中消耗4个字节。因此,当您首先打印outIdx(int)
时,printf从对应于outIdx的堆栈中获取正确的4个字节。当printf看到第二个%d
时,它将使用4个下一个字节,它是time_t对象的8个字节的一部分。并且取决于time_t的值,系统的字节顺序,print将从堆栈中打印4个字节(8个),假设它为int。
当print提供错误的%
标识符时,您最终可能会弄乱其堆栈排列并可能会出现不正确或未定义的行为。