C++ 在Rcpp(C+;+;)中的同一代码中多次声明变量
对于开始使用Rcpp的R用户来说,声明变量是一件新鲜事。我的问题是,当同一个命名变量被多次声明时,实际会发生什么。在许多示例中,我看到每次都会声明for循环的索引C++ 在Rcpp(C+;+;)中的同一代码中多次声明变量,c++,rcpp,C++,Rcpp,对于开始使用Rcpp的R用户来说,声明变量是一件新鲜事。我的问题是,当同一个命名变量被多次声明时,实际会发生什么。在许多示例中,我看到每次都会声明for循环的索引 cppFunction(' int add1( const int n ){ int y = 0; for(int i=0; i<n; i++){ for(int j=0; j<n; j++) y++; for(int j=0; j<(n*2); j++) y++;
cppFunction('
int add1( const int n ){
int y = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) y++;
for(int j=0; j<(n*2); j++) y++;
}
return y ;
}
')
cppFunction('
内部地址1(常量内部地址n){
int y=0;
对于(inti=0;i而言,这是因为封装。
你可以尝试的是
for(int i = 0; i<5;i++) {std::cout<<i<<std::endl; }
std::cout<<i<<std::endl;
现在您再次尝试声明同一个变量,这会给您一个错误。这是因为封装。
你可以尝试的是
for(int i = 0; i<5;i++) {std::cout<<i<<std::endl; }
std::cout<<i<<std::endl;
现在,您再次尝试声明同一个变量,这会给您带来一个错误。在您给出的两个示例中,选择哪一个变量不会有太大区别-编译器几乎肯定会对它们进行相同的优化
两者都是完全合法的。您引用的第二种情况是可以的,因为每个变量都包含在for循环的范围内
就我个人而言,我总是像你的第二个例子那样编写循环,除非循环的索引与其他预先存在的变量相关。我认为这是一个更简洁的解决方案,符合在需要变量的地方声明变量的想法
C/C++将允许您执行一些不完全直观的操作—它将允许您在嵌套范围内重新定义相同的变量名,然后事情可能会变得一团糟:
for (int i = 0; i < 10; i++) {
for (int i = 10; i < 100; i++) {
// Be careful what you do here!
}
}
for(int i=0;i<10;i++){
对于(int i=10;i<100;i++){
//你在这里做事要小心!
}
}
在内部循环中,对“i”的任何引用都将引用在内部循环中声明的“i”-外部循环“i”现在是不可访问的。我已经看到了很多基于此的错误,它们可能很难被发现,因为程序员几乎从来都不是故意选择的。在您给出的两个示例中,使用哪一个不会有多大区别hoose-编译器几乎肯定会对它们进行相同的优化
两者都是完全合法的。您引用的第二种情况是可以的,因为每个变量都包含在for循环的范围内
就我个人而言,我总是像你的第二个例子那样编写循环,除非循环的索引与其他预先存在的变量相关。我认为这是一个更简洁的解决方案,符合在需要变量的地方声明变量的想法
C/C++将允许您执行一些不完全直观的操作—它将允许您在嵌套范围内重新定义相同的变量名,然后事情可能会变得一团糟:
for (int i = 0; i < 10; i++) {
for (int i = 10; i < 100; i++) {
// Be careful what you do here!
}
}
for(int i=0;i<10;i++){
对于(int i=10;i<100;i++){
//你在这里做事要小心!
}
}
在内部循环中,对“i”的任何引用都将引用在内部循环中声明的“i”-外部循环“i”现在不可访问。我已经看到了很多基于此的错误,它们可能很难被发现,因为程序员几乎从来没有刻意选择过它。Overview
> Alty,让我们在编译器对两个语句都进行了转换之后,查看汇编代码。在这种情况下,编译器应该理想地提供相同的优化(我们可能想用-O2标志运行)。
测试用例
< >我用纯C++编写了你的文件,也就是说,我选择直接通过终端进行编译,而不是依赖于<代码> Rcpp <代码> >在<编译> >中包含的“黑魔法”包括< /代码>。
测试.cpp
#include <iostream>
int add2( const int n ){
int y = 0;
int i, j;
for(i=0; i<n; i++){
for(j=0; j<n; j++) y++;
for(j=0; j<(n*2); j++) y++;
}
return y ;
}
int add1( const int n ){
int y = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) y++;
for(int j=0; j<(n*2); j++) y++;
}
return y ;
}
int main(){
std::cout << add1(2) << std::endl;
std::cout << add2(2) << std::endl;
}
这给出了我在文章末尾分块的以下带注释的输出
基准是王道
另一种验证的方法是做一个简单的微基准测试。如果两者之间存在显著差异,这将为不同的优化提供证据
# install.packages("microbenchmark")
library("microbenchmark")
microbenchmark(a = add1(100L), b = add2(100L))
给出:
Unit: microseconds
expr min lq mean median uq max neval
a 53.081 53.268 55.35613 53.576 53.8825 92.078 100
b 53.069 53.261 56.28195 53.431 53.6795 169.841 100
Unit: microseconds
expr min lq mean median uq max neval
b 53.112 53.3215 60.14641 55.0575 60.7685 196.865 100
a 53.130 53.6850 58.72041 55.2845 60.6005 93.401 100
切换顺序:
microbenchmark(b = add2(100L), a = add1(100L))
给出:
Unit: microseconds
expr min lq mean median uq max neval
a 53.081 53.268 55.35613 53.576 53.8825 92.078 100
b 53.069 53.261 56.28195 53.431 53.6795 169.841 100
Unit: microseconds
expr min lq mean median uq max neval
b 53.112 53.3215 60.14641 55.0575 60.7685 196.865 100
a 53.130 53.6850 58.72041 55.2845 60.6005 93.401 100
本质上,基准本身表明两种方法之间没有显著差异
附录
长输出
长输出add1
输出短输出
add1的短输出
概述
> Alty,让我们在编译器对两个语句都进行了转换之后,查看汇编代码。在这种情况下,编译器应该理想地提供相同的优化(我们可能想用-O2标志运行)。
测试用例
< >我用纯C++编写了你的文件,也就是说,我选择直接通过终端进行编译,而不是依赖于<代码> Rcpp <代码> >在<编译> >中包含的“黑魔法”包括< /代码>。
测试.cpp
#include <iostream>
int add2( const int n ){
int y = 0;
int i, j;
for(i=0; i<n; i++){
for(j=0; j<n; j++) y++;
for(j=0; j<(n*2); j++) y++;
}
return y ;
}
int add1( const int n ){
int y = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++) y++;
for(int j=0; j<(n*2); j++) y++;
}
return y ;
}
int main(){
std::cout << add1(2) << std::endl;
std::cout << add2(2) << std::endl;
}
这给出了我在文章末尾分块的以下带注释的输出
基准是王道
另一种验证的方法是做一个简单的微基准测试。如果两者之间存在显著差异,这将为不同的优化提供证据
# install.packages("microbenchmark")
library("microbenchmark")
microbenchmark(a = add1(100L), b = add2(100L))
给出:
Unit: microseconds
expr min lq mean median uq max neval
a 53.081 53.268 55.35613 53.576 53.8825 92.078 100
b 53.069 53.261 56.28195 53.431 53.6795 169.841 100
Unit: microseconds
expr min lq mean median uq max neval
b 53.112 53.3215 60.14641 55.0575 60.7685 196.865 100
a 53.130 53.6850 58.72041 55.2845 60.6005 93.401 100
切换顺序:
microbenchmark(b = add2(100L), a = add1(100L))
给出:
Unit: microseconds
expr min lq mean median uq max neval
a 53.081 53.268 55.35613 53.576 53.8825 92.078 100
b 53.069 53.261 56.28195 53.431 53.6795 169.841 100
Unit: microseconds
expr min lq mean median uq max neval
b 53.112 53.3215 60.14641 55.0575 60.7685 196.865 100
a 53.130 53.6850 58.72041 55.2845 60.6005 93.401 100
本质上,基准本身表明两种方法之间没有显著差异
附录
长输出
长输出add1
输出短输出
add1的短输出
请看下面。我添加了一篇检查编译结果的文章。请看下面。我添加了一篇检查编译结果的文章。