C/C++ メモ

任意の数値をBCDに変換する / double dabbleアルゴリズム / C

型指定する以外はCもPythonと同じように書ける。 #include <iostream> using namespace std; uint16_t bin2bcd_dubdab(uint16_t _bin) { uint8_t BITS_BCD = sizeof(_bin) * 8; uint16_t bcd = 0; for (int i = BITS_BCD - 1; i > 0; i--) { bcd = (uint32_t)(bcd) << </iostream>…

ハミング重み / C

1の個数を数える。マスクをずらしていって、そこに1が立っていたらインクリメントする。 #include <iostream> using namespace std; uint8_t hamming_weight(uint16_t val){ uint8_t sum = 0; for(int i=0; i<16; i++){ if((1 << i) & val) sum++; } return sum; } int</iostream>…

インラインアセンブラ(x86系MASM, Microsoft Macro Assembler)

動かしてわかる CPUの作り方10講, pp.17-20 1+2+ ... +10=55を計算する。 #include <iostream> int main(void){ uint16_t sum; __asm { mov ax, 0 mov bx, 1 LOOP1: cmp bx, 11 // cmpはcompare je MOUT // jeはjump if equal add ax, bx inc bx jmp LOOP1 MOUT: mov </iostream>…

float (単精度浮動小数点数)の内部表現(ビットフィールドも使う)

ビットフィールドを使えばビット演算をしなくても任意のビットにアクセスできるのであった。 #include <iostream> using namespace std; int main(void) { struct each_part { uint32_t mantissa : 23; uint32_t exp_part : 8; uint32_t sign : 1; }; union float_inte</iostream>…

float (単精度浮動小数点数)の内部表現(共用体を使う)

共用体を使えばもっと簡単に内部表現が確認できるのであった。 #include <iostream> using namespace std; int main(void) { union float_internal { float f; uint32_t i32; uint8_t i8[4]; }; float_internal a; a.f = -123.456; printf("0x%X\n", a.i32); printf("0</iostream>…

float (単精度浮動小数点数)の内部表現

参考: 日経ソフトウエア 2020年1月号 [雑誌], pp.144-145 4バイトで表現される。今回実行した環境ではリトルエンディアンで格納されていた(下位バイトが若いアドレスに格納される)。 その4バイトの最上位ビットが符号(0: 正, 1: 負)、 続く8ビットが指数部(…

ヴィジュネル暗号

pp.437-438 これでAVR Programming: Learning to Write Software for Hardware (Make: Technology on Your Time)は終わりにする。 アルファベットだけでなくスペース(0x20)からチルダ(0x7E)までを使うことにする。テキストはエンコードとデコードとで函数を…

連結リスト / ノードを動的に作る

参考: 日経ソフトウエア 2019年 9 月号, pp.77-83 標準入力から文字列が入力されるたびにその文字列を新たなノードとして作成する。 #include <stdio.h> #include <stdlib.h> #include <string.h> struct Node{ char data[20]; Node* next; // 次ノードアドレス }; int main(){ char s[80]</string.h></stdlib.h></stdio.h>…

連結リスト

参考: 日経ソフトウエア 2019年 9 月号, pp.77-83 何に使うのかわからない。 #include <iostream> #include <string> using namespace std; // 構造体Nodeを定義する。 struct Node { string stationName; // 現在位置 Node* next; // 次の位置(自己参照する) Node* prev; // </string></iostream>…

ポインタ変数 / ポインタ変数を使う標準函数

日経ソフトウエア 2019年 7 月号, pp.126-132 アドレスを引数に取る函数(scanf_s()函数) #include <stdio.h> int main() { int int_val; float float_val; printf("Enter an integer: "); scanf_s("%d", &int_val); // 変数のアドレスを引数として渡して、その変数に</stdio.h>…

STLの各種アルゴリズムを試してみる

参考: スラスラわかるC++ 第2版, pp.397-404 <algorithm>をインクルードする。 sort()、find()、count()、reverse()、replace()を試してみる。 #include <iostream> #include <vector> #include <algorithm> using namespace std; int main(){ // 適当に可変長排列を宣言しておく。 vector <int> arr = {1,</int></algorithm></vector></iostream></algorithm>…

stackコンテナ / LIFO (後入れ先出し)タイプのデータ格納方式

<stack>をインクルードする。 #include <iostream> #include <stack> using namespace std; int main() { stack <int> st; // intを格納するスタックを変数stとして宣言する。 for (int i = 0; i < 5; i++) { st.push(i); // .push()でスタックに値を格納する。 } while (!st.empty()) { c</int></stack></iostream></stack>…

queueコンテナ / FIFO (先入れ先出し)タイプのデータ格納方式

<queue>をインクルードする。 #include <iostream> #include <queue> using namespace std; int main(){ queue <int> qu; // intを格納するキューを変数quとして宣言する。 for (int i = 0; i < 5; i++) { qu.push(i); // .push()でキューに値を格納する。 } while (!qu.empty()) { cout <</int></queue></iostream></queue>…

mapコンテナ / 聯想排列

<map>をインクルードする。 #include <iostream> #include <map> using namespace std; int main() { map <char, int> dict; // 聯想排列dictを宣言する。 int val = 0; for (char key = 'A'; key < 'F'; key++) { dict.insert(make_pair(key, val)); // make_pair()でキーと値とのペアを作</char,></map></iostream></map>…

vectorコンテナ / 可変長排列

<vector>をインクルードする。 #include <iostream> #include <vector> using namespace std; int main(){ vector <int> arr; // 可変長排列arrを宣言する。 arr = {0,1,2}; for (int i = 0; i < arr.size(); i++) { // .size()で要素の数が取得できる。 cout << arr[i] << ","; } cout << e</int></vector></iostream></vector>…

クラステンプレートを使ってクラスを定義する

#include <iostream> using namespace std; template <class dtype1, class dtype2> class Sute { private: dtype1 a; dtype2 b; public: Sute(dtype1 a, dtype2 b) { // コンストラクタ this->a = a; this->b = b; } dtype2 conv() { return (dtype2)this->a; } }; int main(){ Sute <int, char> test1(65, '1</int,></class></iostream>…

函数テンプレートを使って函数を定義する

#include <iostream> using namespace std; // 普通の方法。 char sute(int a) { return (char)a; } int sute(char a) { return (int)a; } // 函数テンプレートを使う方法。dtypeが任意のデータ型を表す。ここでは"dtype"にしたが記号は何でもよい。 // 函数テンプレー</iostream>…

ポインタ変数 / *と&の使いかた

参考: 日経ソフトウエア 2019年 5 月号, pp.90-97 変数に割り振られたアドレスを取り出すときは&変数という構文を使う。 ポインタ変数も変数なので、自身に代入されたアドレスとは別に、自身に割り振られたアドレスがある。 ポインタ変数を宣言するときは型 …

ダンププログラムを作る

参考: スラスラわかるC++ 第2版, pp.360-373 main函数をint main(void)にはせずにint main(int 引数の数, char *引数排列[])のようにして実行時に引数が渡せるようにする。char *引数排列[]はポインタの排列。 下の実行例では、引数排列[0]に"ConsoleApplica…

バイナリファイルから何かを読み込む

ifstream インスタンス名("ファイルパス", ios::in | ios::binary)でifstreamクラスをインスタンス化する。これで読み込み元のファイルがひらかれる。 ios::inはファイルからの読み込み、ios::binaryはバイナリファイルの意味。 .get()函数で1バイトずつ読み…

バイナリファイルに何かを書き込む

ofstream インスタンス名("ファイルパス", ios::out | ios::binary)でofstreamクラスをインスタンス化する。これで書き込み先のファイルがひらかれる。 ios::outはファイルへの書き込み、ios::binaryはバイナリファイルの意味。 .put()函数で1バイトずつ書き…

テキストファイルから何かを読み込む

参考: スラスラわかるC++ 第2版, pp.352-353 fstreamをインクルードする。fはfileのf。 ifstream インスタンス名("ファイルパス")でifstreamクラスをインスタンス化する。これで読み込み元のファイルがひらかれる。 ifstreamの"if"は"input file"。 #include <iostream></iostream>…

テキストファイルに何かを書き込む

fstreamをインクルードする。fはfileのf。 ofstream インスタンス名("ファイルパス")でofstreamクラスをインスタンス化する。これで書き込み先のファイルがひらかれる。 ofstreamの"of"は"output file"。 #include <iostream> #include <fstream> using namespace std; int main</fstream></iostream>…

例外でエラーを知らせる / 例外の型ごとにcatchブロックを設ける

#include <iostream> #include <string> using namespace std; int main(){ for (int i = 0; i < 5; i++) { try { switch(i) { case 0 : throw i ; break; // int型の例外を投げる。 case 1 : throw string("1.0000"); break; // string型の例外を投げる。 case 2 : throw 2.1 </string></iostream>…

例外でエラーを知らせる / 型の異なる複数の例外をcatch(...)で捕まえる

#include <iostream> #include <string> using namespace std; int main(){ for (int i = 0; i < 3; i++) { try { switch(i) { case 0 : throw i ; break; // int型の例外を投げる。 case 1 : throw "1.0000"; break; // string型の例外を投げる。 case 2 : throw 3.0 ; break;</string></iostream>…

例外でエラーを知らせる

まずtryブロックを実行してみて、異常系の処理だった場合はthrowで投げてcatchブロックで捕まえる。noexcept(false)を一往つけたが下の例では不要。 #include <iostream> #include <string> using namespace std; double divi(double a, double b) noexcept(false) { //double </string></iostream>…

演算子のオーバーロード

ベクトルの加算ができるよう、operatorキーワードを使って加算演算子(+)をオーバーロードしてみる。 #include <stdio.h> class Vect { private: double x, y; // 座標を格納するメンバー変数 public: // コンストラクター Vect(double x, double y) { this->x = x; th</stdio.h>…

函数のオーバーロード(多重定義)とデフォルト引数

引数が違えば同じ名前の函数が複数定義できる。デフォルト引数はプロトタイプ宣言のほうか実装のほうかどちらか一方にだけ指定する。 #include <stdio.h> int sum(int a=100, int b=200){ return a + b; } double sum(double a, double b, double c){ return a + b + </stdio.h>…

十進数値の各桁を取り出す

#include <stdio.h> void getDigits(unsigned char UINT_8T){ int d100 = UINT_8T / 100; // 百の位。整数型なので小数点以下は切り捨てられる。 int d10 = UINT_8T / 10 % 10; // 十の位 //int d10 = UINT_8T % 100 / 10; // 十の位 int d1 = UINT_8T % 10; // 一の</stdio.h>…

英数字のASCIIコード

'a'をインクリメントすれば'b'、'b'をインクリメントすれば'c'、...... 。大文字も数字も同様。 #include <stdio.h> int main(){ for(unsigned char str='a'; str<'f'+1; str++){ printf("0x%x: %c\r\n", str, str); } } ―――――――――――――――――――――――――――――――― こうすれば</stdio.h>…