ATLAS日本基礎ネットワーク C++トレーニングコース

第一回 イントロダクション

ここでの目標

目次

1.動作環境

C++で作業するための環境をまず確認しましょう。

ATLASでのデータ解析を想定しているので、次のような環境を前提としています。

計算機の種類
インテル系PC
オペレーティングシステム
CERN Scientific Linux 6 (SLC6)
C++コンパイラ
GCC 4.4.7

自分が使えるOSやコンパイラを確認しましょう。

g++ --version

g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-18)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

GCCが使えることがわかりました。次に作業をするための場所を用意しましょう。

この文書ではキーボード入力する部分を赤字で、計算機がそれに対して表示する部分を青字で表示しています。

プログラムソースは緑字で表示されます。

現在、ホームディレクトリ(ログインした最初にいるディレクトリ)にいます。

$HOME/tutorial/cplusplus/l1 を作業場所として選びました。

2.Hello, World!

早速ですからお約束のHello, World!をやりましょう。テキストエディタを起動してソースコードを書きましょう。ファイル名はhello.cxxとしましょう。

#include <iostream>
main() {
    using namespace std;
    cout << "Hello, World!" << endl;
}

テキストエディタを終了して、ファイルが出来ていることを確認します。

ls

hello.cxx

ではここでコンパイルします。

g++ hello.cxx

問題なくコンパイルされたでしょうか。

ls

a.out hello.cxx

うまくいくとa.outというファイルが出来ているはずです。実行してみましょう。

./a.out

Hello, World!

期待通りになりました。./a.outという表現は、このディレクトリ(.)にあるa.outというファイルを実行するという意味です。

3.Hello, World!のソースコードの意味

それではソースコードを見ていきましょう。

#include <iostream>

この行は、第一コラムが#ですので、プリプロセッサが解読する命令と言うことになります。includeですから、iostreamというファイルを読み込もうと言うことを示しています。試しにプリプロセッサがどのように働くか見てみましょう。プリプロセッサコマンドはcppです。

cpp hello.cxx | more

いろいろなものが表示されました。主にtypedefなどの型宣言です。これにより、ストリーム入出力(iostream)を行うために必要な定義が読み込まれるわけです。

ここでもう一つの情報がわかります。#includeというプリプロセッサ命令で/usr/include/c++/3.4.6/というところにあるファイルが読み込まれていることがわかります。

ls /usr/include/c++/4.4.7

algorithm cstdarg functional sstream
array cstdatomic initializer_list stack
backward cstdbool iomanip stdatomic.h
bits cstddef ios stdexcept
bitset cstdint iosfwd streambuf
c++0x_warning.h cstdio iostream string
cassert cstdlib istream system_error
ccomplex cstring iterator tgmath.h
cctype ctgmath limits thread
cerrno ctime list tr1
cfenv cwchar locale tr1_impl
cfloat cwctype map tuple
chrono cxxabi-forced.h memory typeinfo
cinttypes cxxabi.h mutex type_traits
ciso646 debug new unordered_map
climits deque numeric unordered_set
clocale exception ostream utility
cmath exception_defines.h parallel valarray
complex exception_ptr.h queue vector
complex.h ext random x86_64-redhat-linux
condition_variable fenv.h ratio
csetjmp forward_list regex
csignal fstream set

なにやらいろいろありそうです。これらの勉強はまたそのうち。

次に

main() {

これは大域関数mainがここで定義されていることを示します。mainは特殊な関数で、エントリーポイントとなります。実行可能形式(a.out)を作ったとき、そのプログラムのどこから実行を開始したらよいかを表します。C++の場合、main関数に制御が渡されます。それ故、実行可能形式を作るときは必ず一つmain関数を用意しなければなりません。

C++では関数は値を返す〜戻り値を持つ必要があります。古いC言語との互換性のために、「戻り値を明示しないときは整数型である」というルールがあります。このmain関数はですから整数型の関数です。return文で戻り値を明示していないためデフォルト値0が返されます。

using namespace std;

この行の意味は、この先にmain関数の中で出てくるシンボル・変数名などはstdという名前空間にあるものと思えと言う宣言です。具体的にはcoutendliostreamというファイルで定義されているのですが、それらの定義はすべてstdという名前空間の中で行われています。

C++プログラムの中に現れるものはいずれかの名前空間に属します。

教科書によっては#include <iostream.h>というように、後ろに.hをつけたものが書かれているものもあります。<iostream.h><iostream>の違いは、前者が古い定義で匿名名前空間でクラスや型を定義しているのに対し、後者はstdという名前空間内にそれらを定義しています。名前空間については後日詳細に説明します。

このusing namespaceを記述しない場合、次に述べるcoutendlstdという名前空間に属することを示すためにそれぞれ、std::coutstd::endlという風に直接名前空間を指定する必要があります。

cout << "Hello, World!" << endl;

文法上はcoutというオブジェクトのオペレータ(関数の一種)<<を、文字列"Hello, World!"を引数として呼び出します。その結果、cout<<"Hello, World!"という式が返すオブジェクトに対し、iostreamで定義されたendlというオブジェクトを引数としてオペレータ<<を呼び出します。(cout<<"Hello, World!")<<endl

意味がわかりますか?

効果としてはコンソール出力std::coutに文字列"Hello, World!"を出力(<<)した後、改行(std::endl)を出力すると考えてよいのですが。

プログラム開発をするときは自分が意図した概念が正しくソースコードに記述されているかどうか確認をすることが重要です。上に述べたような構文解読の習慣をつけましょう。

}

これで関数mainが閉じられます。

4.My First Class

我々がC++を使うのはそれがオブジェクト指向技術と呼ばれるものに基づいて設計された言語であるからです。その基本的な構成要素であるオブジェクトはクラスというある種の型に基づいて生成されます。クラスを設計することがプログラム開発の上で非常に大きな比重を占めます。

ここはイントロですから、詳細は後回しにして、雰囲気をつかみましょう。MyFirstClass.cxxというファイルを作ります。

// MyFirstClass.cxx
#include <iostream>
 
class MyFirstClass {
 
public :
    void printHello( ) {
         using namespace std;
         cout << "Hello, World!" << endl;
    }
};
 
main( ) {
    MyFirstClass myObject;
    myObject.printHello( );
}

同様にコンパイル、実行をしてみましょう。

g++ MyFirstClass.cxx

./a.out
Hello, World!

実行結果は前の例と同じですが、ソースコードはずいぶん複雑になっています。

// MyFirstClass.cxx 

まずこの行はコメント行です。C++では、//はコメント導入を示し、行末までがコメントになります。

もう一つのコメントの表し方は/**/で囲むもので、これは複数行にわたっても有効です。

/* */の中に/* */の対を入れることは出来ません。/*の後に再び/*が来ても、それはコメントの一部と思われるため、無視。一方、最初に出現した*/でコメントは終わりと取られます。その次から最後の*/まではコメントではなくプログラムソースだと思われるため、たいがいエラーになります。時々やりますからご注意を。

#include <iostream> 
これは先ほどと同じ。コンソールへの書き出しをしたいので読み込みます。

class MyFirstClass {
 
public : 
    void printHello( ) {
        using namespace std; 
        cout << "Hello, World!" << endl;
     }
 }; 

この部分でクラスMyFirstClassを定義しています。パブリックなメソッド(メンバー関数)printHelloを持つだけのクラスで、このメソッドは先の例と同じHello,World!をコンソールに出力するものであることがわかります。あくまでもここはクラスとそのメソッドの定義部分です。

main( ) {
    MyFirstClass myObject; 
    myObject.printHello( ); 
}

ここがエントリーポイントであるmain関数です。関数の中でクラスMyFirstClassのオブジェクトmyObjectを定義します。オブジェクトとして作られることでクラスの機能は初めてコンピュータメモリー上に存在し、実行可能になります。myObject.printHello()myObjectというオブジェクトのprintHelloというメソッドを呼び出しています。myObjectMyFirstClassクラスで作られたオブジェクトですからprintHelloというメソッドを持っています。

コンソールに表示がされるのはmain関数が呼ばれ、myObjectが生成され、その次にprintHelloに制御がわたったときです。どのオブジェクトのどのメソッドが実行されているかを正しく追いかけることは非常に重要です。

この文書で使われる様々なものの名前の付け方やコーディングスタイルはATLAS C++ Conding Standard (ATL-SOFT-2002-001)に基づいています。出来るだけこの文書のスタイルに近づけることにより、ATLASのルールに従ったコーディングが出来るよう配慮しています。

次回はデータの扱い方について勉強しましょう。


上へ 次へ


2017年7月20日更新