Fu-koの足跡

コンピュータが苦手です。得体のしれない感じに抵抗があります。考えるのは好きです。すっきりしたロジックに感動します。ちゃんと理解すれば好きになれるはずと信じて、その過程を残そうと思います。

配列やリストの要素数

使うたびに調べてる気がする。。。

C#
配列

int[] array = new int[] {1, 2, 3};
System.Console.WriteLine(array.Length);

List

List<int> list = new List<int> {1, 2, 3};
System.Console.WriteLine(list.Count);

Java
配列

int array[] = {1, 2, 3};
System.out.printlin(array.length);

List

List<Integer> list = new ArrayList<>(3);
list.add(1);
list.add(2);
list.add(3);
System.out.printlin(list.size());

JavaScript
配列

var array = [1, 2, 3];
console.log(array.length);

Javascript入門中

掲題の通り、今更ながらJavaScriptの勉強を始めました。
動機は社内報を書くため。目的があるとはかどります。

で、早速困った。
IE11を使用していますが、参考書でまず初めにやっているconsole.log()がundefinedになる。
ちなみにディベロッパーツール上のコンソールに直接書いて実行させてます。
Webで検索してみると使えないというような情報も見かけるけど、なんかぱっとしない。
どうしたものか。。。

ちなみにhtmlファイルのscriptタグ内に書いて
デバッグ実行した場合は期待通り動きました。

.jsに書いて読み混んだらConsolが定義されていないと怒られました。

さて、何が起きているのでしょうか。。。


# 以前はこういうので挫折してたな。。。
# こんなんよくあることと思って、次に進めるようになったのは成長かな。

インクリメント演算子がない

CやC++に慣れているので、つい

n++

と書いてしまい怒られます。

n += 1

のように書く必要があるようです。

これは値もオブジェクトとして扱ってることが背景にあるようです。
元来「++」は変数を操作する演算子であり、オブジェクトを操作する演算子ではありません。
また、オブジェクトが指す数値を切り替えてしまうと

n=1
n++

の場合、「1」を指すオブジェクトを「2」を指すオブジェクトに変更する、i.e.「1=2」になってしまい変になる、ということらしい。

「n += 1」は「n = n + 1」のシンタックスシュガーなので、意図通りに動きますが、「n += 1」はどちらかといえば「n++」と同等に見えるので、変な感じがします。

iniファイルの読み書き

namespace Sample
{
    class SampleClass
    {
        [DllImport("kernel32.dll")]
        private static extern int GetPrivateProfileString(
            string lpApplicationName,
            string lpKeyName,
            string lpDefault,
            StringBuilder lpReturnedstring,
            int nSize,
            string lpFileName);

        [DllImport("kernel32.dll")]
        private static extern int WritePrivateProfileString(
            string lpApplicationName,
            string lpKeyName,
            string lpstring,
            string lpFileName);

        // 設定ファイルに指定されたキーに対応する値を設定
        public void SetKeyValue(string strTargetFile,
                                string strSection,
                                string strKey,
                                string strValue)
        {
            WritePrivateProfileString(
                strSection,
                strKey,
                strValue,
                strTargetFile);
        }

        // 設定ファイルから指定されたキーに対応する値を取得
        public string GetKeyValue(string strTargetFile, 
                                  string strSection,
                                  string strKey)
        {
            // iniファイルから文字列を取得
            StringBuilder sb = new StringBuilder(1024);

            GetPrivateProfileString(
                strSection,
                strKey,
                "",
                sb,
                Convert.ToInt32(sb.Capacity),
                strTargetFile);

            return sb.ToString();
        }
    }
}

std::vectorのソート

std::vectorはstd::sortを使ってソートできる。
以下は簡単なソートの例。

<ソース>

#include <iostream>
#include <vector>
#include <algorithm>	// for std::sort
#include <functional>	// for std::greater

void main()
{
	std::vector<int> vec;
	vec.push_back(3);
	vec.push_back(1);
	vec.push_back(2);

	// 昇順ソート
	std::sort(vec.begin(), vec.end());
	for (int i = 0; i < vec.size(); i++) std::cout << vec.at(i) << std::endl;

	std::cout << std::endl;

	// 降順ソート
	std::sort(vec.begin(), vec.end(), std::greater<int>());
	for (int i = 0; i < vec.size(); i++) std::cout << vec.at(i) << std::endl;
}

<実行結果>

1
2
3

3
2
1

std::sortの第3引数に自前の比較関数を指定することで、
クラス型の要素のvectorもソートできる。

コマンドラインからのコンパイル

VC++コマンドラインからのビルドで複数ファイルをビルドするには、
対象ファイルを列挙すればよい。

Main.cpp :exeを作りたいファイル
Class[n].cpp:クラスの実装ファイル

cl /EHcs Main.cpp Class1.cpp Class2.cpp Class3.cpp


オプション「/Gm /Zi」を付けると、変更があったファイルのみ再コンパイルする。

cl /EHcs /Gm /Zi Main.cpp Class1.cpp Class2.cpp Class3.cpp

簡易ビルドの有効かオプション「/Gm」は、追加オプション「/Zi」or「/ZI」でデバッグ情報の形式を指定する必要がある。(「/Z7」は指定不可)

  • 「/Zi」を指定すると、型情報とシンボリック情報から成るPDBが生成される。シンボリック情報には、変数名、関数名、型、行番号が含まれる。
  • 「/Zi」を指定すると、「/debug」が暗黙的に指定される。

トークン分割

std::stringにsplit関数がないので、std::getlineを使って分割する。

<ソース>

#include <iostream>
#include <vector>
#include <sstream>
#include <string>

int main()
{
	std::vector<std::string> vec;
	std::string str;

	// 読み込み
	std::getline(std::cin, str);

	// ' ' で分割
	std::stringstream ss(str);
	while (std::getline(ss, str, ' ')) // 第3引数で区切り文字を指定
	{
		vec.push_back(str);
	}

	// 分割したトークンを出力
	for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
	{
		std::cout << *it << std::endl;
	}

	return 0;
}

<実行結果>

a bb c dd ee f    ->コンソールからの入力
a
bb
c
dd
ee
f