回答
それは元記事の内容をだいぶ歪めた理解と言うことができます(元記事のミスリードもひどいけど)。
新しいコードに、char、int、short、long、unsignedなどの型を使おうとしているなら、それは誤りです。
とは 整数を格納する型として と捉えるべきです。文字列、ただし一単位が1byteな文字エンコードを格納する型としては、これまで通りchar
型を用いるべきです。
文字列についてはC11/C++11にてUnicode周りの大きな改善(不十分)が追加されたことを知っておくべきです。
まずこれまで
文字リテラル | 型 | 格納される物 |
---|
'' | char | 実装依存 |
L'' | wchar_t | 実装依存(一文字を表すのに十分な大きさの型とあるが、これは実現不可能、UTF-16かUTF-32が現実には使われる |
がありましたが、Unicode対応のため
文字リテラル | 型 | 格納される物 |
---|
u'' | char16_t | UTF-16 |
U'' | char32_t | UTF-32 |
が追加されました。同様に文字列リテラルも存在します。
文字列リテラルに限ってはC11/C++11で
文字列リテラル | 型 | 格納される物 |
---|
u8"" | const char[] | UTF-8 |
が追加されています。
またC++17では
文字リテラル | 型 | 格納される物 |
---|
u8'' | char | UTF-8 |
が追加されています(C言語でどうだったか覚えてない)
ここで重要なこととして、C/C++にはなんとまさかのUTF-8を保証する型が存在しません。
https://cpplover.blogspot.com/2016/09/c-p0370r1-p0379r0.html
C++11のときにchar8_tが必要だと訴えたら、charは古典的にバイト列を表現する型なので十分だ。char型以外の型があるのは混乱する。などと理解のないUnicodeの世界に生きていない名だたる委員達から散々に批判された。その委員達も、今では、「やっぱりchar8_tがないのは失敗だったなぁ」とぼやいている。それ見たことか。
C++11で文字の何たるかを理解できないアスキー文字しか解さないクソどもがUTF-8を保証するchar8_t
型をRejectしたからです。
C++17で再び提案されるもやはりReject。
C/C++標準化委員会の連中は全く文字の何たるかを理解できないと言うことができます。
さて、C++20に向けて再びchar8_t
型が提案されています。
もしchar8_t
型が標準入りしたならば、もはやchar
は使うべきではないと言えるでしょう。
整数型について、stdint.h
/cstdint
ヘッダーに定義されるintN_t
型を用いよ、という主張は正しいと言えなくもないです。大きさが明確に定まっているべきbinary formatに対応する構造体/trivialy copyable classの要素型であるとか、他の言語から使われることを想定するC APIなどは必ずこれを用いるべきです。またそうでない場合も2の補数系を仮定できるとか1byte=8bitを仮定できるなど考えうことが減り、たかが差の絶対値を計算するのに
C/C++はnull安全になる前に安全に差の絶対値を計算できるようになるべきではないか - Qiita#つまり安全に差の絶対値を計算できるようにはどうすればいいのか
のようなコードを書かずに済んだりと恩恵があります。
話がそれました。戻しましょう。
正直C++でC言語の関数を使わない方が良いんでしょうか??
C++に便利な関数群が十分存在していてそのほうが楽だからそちらを使う、ただそれだけのことです。
ご自分でも
関数のパラメータ用にSTLコンテナから要素を取り出し、いちいち型を変換しなくてはいけないのが、かなり面倒です。
と書かれているじゃないですか。プログラマーは怠惰であるべきなので、STLを使うほうが楽できます。STLの関数群/クラス群の使い方を調べるには
https://cpprefjp.github.io/
が便利です(宣伝)
ただしiostream系はC++のstd::cout
のようなスタイルやCのprintf
のようなスタイルともに明らかな問題が存在し、fmtlib/fmtとかを使うべきだということができます。またlocaleはだいたいC/C++問わずぶっ壊れていて使い物になりません
以下余談。
std::stringのc_str()関数ってchar型のポインタですよね。
違います。const修飾されている=const char *
型です。C++はconst性についてかなり厳密に扱います。
C/C++にはUnicodeどうしの文字コード変換を行う方法が存在しないという状態が生じています(C++11で入ったが致命的な欠陥が見つかってC++17でdeprecated)
C APIで文字列を受け取る場合のAPI設計について留意するべきことがあります。
Cだけやっていると
のようなAPIを作りがちですが、2つの点からこれをするべきではありません。
- 文字列の長さがNULL終端文字に依存している
Cでは文字列とはNULL終端するbyte列のことでしたが、これはプログラミングをする上で余計なメモリ確保を強いる事があり、非効率的です。
C++ですらC++17でstring_view
なるものが追加され、文字列の先頭へのポインタと長さの構造体のようなクラスをstd::string
と同じインターフェースで扱えるようになったことでNULL終端しない文字列を扱う機会が増えます。
- const修飾されていない
const修飾されていないとC++ではこのAPIに文字列リテラルを渡すことができません。
また文字列が書き換えられる可能性があるため安全のために一度動的メモリ確保を行いコピーするコストが発生し、著しく実行速度に影響を与えます。
したがって
c
1void foo(const char* str, size_t len);
のようにしましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/07/07 17:19
2018/07/08 01:54
2018/07/08 05:55
2018/07/08 13:26 編集
2018/07/08 13:33
2018/07/23 10:53
2018/07/24 10:15
2018/10/26 12:05
2018/10/30 00:25
2018/10/30 05:25
2018/10/30 05:43