Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Rcpp(C+;+;)中的同一代码中多次声明变量_C++_Rcpp - Fatal编程技术网

C++ 在Rcpp(C+;+;)中的同一代码中多次声明变量

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++;

对于开始使用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++;
     }
     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的短输出

请看下面。我添加了一篇检查编译结果的文章。请看下面。我添加了一篇检查编译结果的文章。