2012-05-15 9 views
8

मैं सी ++ सीख रहा हूं और मैंने इसे पढ़ने वाली किसी भी पुस्तक में वास्तव में इसे नहीं देखा है। मैं कोड पढ़ना और टिप्पणी करना चाहता था, इसलिए मैं बेहतर सीख सकता हूं और कोड के एक विषम खंड में आया जो चलता है लेकिन इसमें कोई शर्त नहीं है। जो मैंने पढ़ा है (और अन्य भाषाओं के साथ मेरे अनुभव, आपको एक के लिए, जबकि, ब्लॉक के लिए या कुछ चाहिए)।कोड के इस ब्लॉक को समझें (यह किसी भी शर्त के साथ चलता है)

मैं टीबीबी थ्रेड्स पैकेज देख रहा हूं, इसलिए मुझे यकीन नहीं है कि यह थ्रेड या सी ++ विशिष्ट लॉन्च करने से संबंधित है (यदि आप इसे सी ++ में कुछ सामान्य नहीं मानते हैं तो यह संभवतः विशिष्ट विशिष्ट है)।

मुझे लगता है कि मैं समझता हूँ कि क्या कोड के अंदर वास्तव में करता है लेकिन मुझे यकीन है कि कैसे अपनी किया जा रहा है शुरू हो रहा या भाग नहीं हूँ। कोई विचार?

{ 
     //this is the graph part of the code 
     Graph g; 
     g.create_random_dag(nodes); 
     std::vector<Cell*> root_set; 
     g.get_root_set(root_set); 
     root_set_size = root_set.size(); 
     for(unsigned int trial=0; trial<traversals; ++trial) { 
      ParallelPreorderTraversal(root_set); 
     } 
    } 

पश्चलेख:

यहाँ अनुभाग है अगर यह पूरी फ़ाइल में मदद करता है (उपरोक्त कोड मुख्य() के बीच में है)।

#include <cstdlib> 
#include "tbb/task_scheduler_init.h" 
#include "tbb/tick_count.h" 
#include "../../common/utility/utility.h" 
#include <iostream> 
#include <vector> 
#include "Graph.h" 

// some forward declarations 
class Cell; 
void ParallelPreorderTraversal(const std::vector<Cell*>& root_set); 

//------------------------------------------------------------------------ 
// Test driver 
//------------------------------------------------------------------------ 
utility::thread_number_range threads(tbb::task_scheduler_init::default_num_threads); 
static unsigned nodes = 1000; 
static unsigned traversals = 500; 
static bool SilentFlag = false; 

//! Parse the command line. 
static void ParseCommandLine(int argc, const char* argv[]) { 
    utility::parse_cli_arguments(
      argc,argv, 
      utility::cli_argument_pack() 
       //"-h" option for for displaying help is present implicitly 
       .positional_arg(threads,"n-of-threads","number of threads to use; a range of the form low[:high], where low and optional high are non-negative integers or 'auto' for the TBB default.") 
       .positional_arg(nodes,"n-of-nodes","number of nodes in the graph.") 
       .positional_arg(traversals,"n-of-traversals","number of times to evaluate the graph. Reduce it (e.g. to 100) to shorten example run time\n") 
       .arg(SilentFlag,"silent","no output except elapsed time ") 
    ); 
} 

int main(int argc, const char* argv[]) { 
    try { 
     tbb::tick_count main_start = tbb::tick_count::now(); //tbb counter start 
     ParseCommandLine(argc,argv); 

     // Start scheduler with given number of threads. 
     std::cout << threads << std::endl; 
     for(int p=threads.first; p<=threads.last; ++p) { 
      tbb::tick_count t0 = tbb::tick_count::now(); //timer 
      tbb::task_scheduler_init init(4); //creates P number of threads 
      srand(2); //generates a random number between 0-2? 
      size_t root_set_size = 0; 
      { 
       //this is the graph part of the code 
       Graph g; 
       g.create_random_dag(nodes); 
       std::vector<Cell*> root_set; 
       g.get_root_set(root_set); 
       root_set_size = root_set.size(); 
       for(unsigned int trial=0; trial<traversals; ++trial) { 
        ParallelPreorderTraversal(root_set); 
       } 
      } 
      tbb::tick_count::interval_t interval = tbb::tick_count::now()-t0; //counter done 
      if (!SilentFlag){ //output the results 
       std::cout 
        <<interval.seconds()<<" seconds using "<<p<<" threads ("<<root_set_size<<" nodes in root_set)\n"; 
      } 
     } 
     utility::report_elapsed_time((tbb::tick_count::now()-main_start).seconds()); 

     return 0; 
    }catch(std::exception& e){ 
     std::cerr 
      << "unexpected error occurred. \n" 
      << "error description: "<<e.what()<<std::endl; 
     return -1; 
    } 
} 
+0

http://en.wikibooks.org/wiki/C%2B%2B_Programming/Scope/Examples - विशेष रूप से "// जटिल स्कोप प्रोग्राम" अनुभाग – WernerCD

उत्तर

18

नहीं, तुम गुंजाइश के एक नए स्तर को पेश करने के लिए एक if या while बयान की जरूरत नहीं है। असल में { प्रतीक एक नया स्कोप स्तर खोलता है और } इसे समाप्त करता है। सामान्य स्कोपिंग नियम लागू होते हैं, उदाहरण के लिए, ब्लॉक ऑब्जेक्ट डिस्ट्रक्टर्स के अंत में, इस नए ब्लॉक के भीतर परिभाषित चर के बाहर अनिर्धारित हैं, और उपरोक्त स्कोप स्तर में दूसरे के समान वैरिएबल छायांकित हो जाएंगे।

switch कथन में एक आम उपयोग केस है। उदाहरण के लिए,

switch (a) 
{ 
    case 1: 
    { 
     int i; 
    } 
    case 2: 
    { 
     int i; //note reuse of variable with the same name as in case 1 
    } 
} 
{ } मामले बयान संकलक गुणा परिभाषित पहचानकर्ता के बारे में शिकायत करेंगे बिना

+0

दिलचस्प..धन्यवाद मैं सोच रहा हूं कि वास्तविक जीवन का उपयोग क्या है? क्या सफाई (मुफ्त, आदि ..) को आसान बनाना या उद्देश्य क्या है? – Lostsoul

+3

हां, इसका उपयोग स्थानीय चर के दायरे पर बेहतर नियंत्रण के लिए किया जाता है, न केवल उन्हें कहां से पहुंचा जा सकता है, बल्कि जब वे स्टैक-आधारित ऑब्जेक्ट होते हैं तो वे मुक्त हो जाते हैं। –

+2

यदि आप चाहें तो आप वही परिवर्तनीय नामों का पुन: उपयोग भी कर सकते हैं, लेकिन बाहरी और आंतरिक में एक ही समानांतर क्षेत्रों में दो के रूप में उपयोगी नहीं है। – chris

2

आप इस तरह के अतिरिक्त ब्लॉक बना सकते हैं। उनका उपयोग अतिरिक्त स्तर के दायरे को लागू करने के लिए किया जाता है। आपके उदाहरण में, जी उस ब्लॉक के पहले या उसके बाद मौजूद नहीं होगा।

7

{ और } की जोड़ी स्थानीय scope बना रही है। दायरे के अंत में संकलक स्वचालित रूप से सभी ढेर चर (यदि कोई मौजूद है) के लिए विनाशकों का आह्वान करेगा जो उस दायरे में घोषित किए गए थे।

आपके मामले में, g और root_set के विनाशकों को दायरे के अंत में बुलाया जाएगा।

थ्रेड के साथ काम करते समय एक म्यूटेक्स लॉक प्राप्त करना एक बहुत ही आम उपयोग है। आइए मान लें कि आपके पास Lock नामक एक क्लास है जो म्यूटेक्स ऑब्जेक्ट स्वीकार करती है और उस पर लॉक प्राप्त करती है। तो फिर तुम समवर्ती पहुँच से रक्षा की जानी करने के लिए इस प्रकार की जरूरत है कि कोड का एक महत्वपूर्ण खंड के चारों ओर कर सकते हैं:

{ 
    Lock lock(mutex); // the Lock constructor will acquire a lock on mutex 

    // do stuff 
} // Here the Lock destructor runs and releases the lock on mutex, allowing 
    // other threads to acquire a lock 

ऊपर करने का लाभ यह है कि { ... } ब्लॉक के भीतर कोड एक अपवाद है, संकलक अभी भी फेंकता है, भले ही Lock का विनाशक यह सुनिश्चित करता है कि म्यूटेक्स लॉक जारी किया गया हो।

4

आप इस तथ्य कोड के ब्लॉक ब्रेसिज़ का एक अतिरिक्त सेट है कि करने के लिए बात कर रहे हैं, कि नहीं C++ प्रोग्रामिंग में असामान्य जब, स्टैक पर अल्पकालिक वस्तुओं के साथ काम कर इस मामले में Graph और std::vector<Cell*> वस्तुओं है। घुंघराले ब्रेसिज़ की एक जोड़ी एक नया गुंजाइश बनाता है।उन्हें किसी भी नियंत्रण कथन से जुड़ा होना जरूरी नहीं है। तो इस मामले में, Graph और vector सुनिश्चित करने के लिए एक अस्थायी दायरा का उपयोग किया जा रहा है जब वे दायरे से बाहर निकलते हैं तो वस्तुओं को तुरंत मुक्त कर दिया जाता है। यदि अतिरिक्त ब्रेसिज़ मौजूद नहीं हैं, तो बाहरी for पाश के अगले पुनरावृत्ति तक वस्तुओं को मुक्त नहीं किया जाएगा।

संबंधित मुद्दे