環境変数とシェル変数の違い
自分なりの理解をまとめておく。
環境変数
プロセスが持つ変数。
親プロセスの持つ環境変数は子プロセスへと引き継がれるが、その逆はない。1
プロセスは自分自身の環境変数を自由に書き換えることができ、例えばenvコマンドなどは環境変数を書き換えたうえで指定されたコマンドを実行するため、書き換えた環境変数が子プロセスへ引き継がれている。
シェル変数
環境変数ではないので、子プロセスから参照できない。
C言語のgetenv関数やmainの第三引数に入る環境変数への配列にもシェル変数は含まれていなかった。
環境変数とシェル変数の違い
環境変数はOSが管理しているが、シェル変数はシェルが管理している。
全ての違いはこれに起因するもの。
重複順列と重複組み合わせ
競プロやっていたら必要になった。
自分なりに理解したことをまとめておく。
重複順列
なんてことはない。
1度選んだものをもう一度選べるというもの。
例えば、1から3の整数の選び方の順列といえば、となるが、
重複順列では一度選んだ整数をもう一度選びなおすことができるため、となる。
重複組み合わせ
重複順列と同じで、1度選んだものをもう一度選べる組み合わせ。
重複順列の組み合わせ版と考えればいい。
ただ、計算方法が少し複雑。
A個の要素を重複を許してB個取り出したときの組み合わせを考えるとき、
B個のマスの間に仕切りをA-1個おき、仕切りで作られた区間をそれぞれ左からA1、A2、A3としていく。
この仕切りの置き方の通りがこの重複組み合わせの答えとなる。
仕切りもマスとして数えた、B+A-1個のマスがあるとして、どこに仕切りを設置するか考える。
この時、B+A-1 C A-1となる。
また、別の考え方として、仕切りを設置しない場所を考えることもできる。
この時、B+A-1 C B であるが、結局のところ上の式と同じようになる。
また、重複をゆする順列の考えを使用し、組み合わせの計算を行うことができる。
仕切りも含めたB+A-1個のマスの並べ方は(B+A-1)!通り。
このうち、B個の重複は無視するのでB!で割る。
さらに、仕切りの重複も無視するので(A-1)!で割る。
変数定義が関数宣言と間違われる
例えば以下のように stdio.h をインクルードしなくとも、コンパイラは警告も何も発しません。
int main() { int puts(const char *); puts("Hello World!"); }
ローカルに宣言された関数識別子の有効範囲はそのスコープ内ですので、別のスコープ(例えば別の関数)から使用しようとするとコンパイラに怒られます。
さて、関数宣言構文は引数識別子を括弧でくくっても構いません。
つまり以下のコードは普通にコンパイルできます。
void f(int(n)) { printf("%d\n", n); }
さらに、C++では関数の引数識別子を省略してしまうことができます。
void f(int()) { cout << "?" << endl; }
そして、この識別子を括弧でくくり、識別子を省略した関数宣言はローカルに記述すると以下の様な見た目になります。
int main() { void f(int()); }
まだわかりずらいですね。
では、構造体 point を返す関数をローカルに宣言してみましょう。
int main() { point f(int(), int()); }
はい。
これは、識別子を省略した関数宣言にも、point型の変数を定義しているようにも見えます。
私の環境ではこれは関数宣言と解釈されました。
-
定義はできません↩
ローカルスコープで関数を宣言する場合
ローカルスコープで関数を宣言する場合、extern
以外の明示的な記憶域クラス指定子を持ってはならない。
重複を許す順列
6つのアルファベットの並べ方について考えます。
ただし、同じ種類のアルファベットを交換しただけのようなものは区別しません。
つまり、をとしたとき、
この2つは区別されません。
も同様です。
どう計算したらいいのでしょうか?
重複を取り除いていく考え方をします。
のすべての文字を区別した際の並べ方はです。
また、のダブりとのダブりはのすべてに対して発生しているため、の並べ方であるとの並べ方であるでを割ってあげます。
つまり、となります。
さて、次は組み合わせ(Combination)の視点から見てみましょう。
全体でアルファベットは6つの場所に置くことができます。
そのうち、を置く場所は2つになり、重複は数えません。
これはそのまま組み合わせに適応できます。
からBの重複を数えない並べ方は[tex: {}6 C_2]です。
また、Bを抜いた全体4からは3つの場所におけるので、からBとCの重複を数えない並べ方は[tex: {}6 C_2 \times {}_4 C_3]となります。