【初心者歓迎】C/C++室 Ver.103【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります
コードを貼れる所
http://codepad.org/
https://ideone.com/
前スレ
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/ 「戻り値ではなく、引数の書き換えで呼び出し元に新たな値を渡したい」
・関数側宣言はポインタで受けて 呼び出し側は変数に&つけてポインタを渡す (c/c++)
関数実装の際 *でデリファレンスして代入
・関数側宣言は参照で受けて 呼び出し側は変数をそのまま渡す (c++)
関数実装の際 そのまま代入 >>582
freeしたあと確実にNULL代入したいためにポインタのポインタで管理しておくことはある あと二重ポインタとかダブルポインタとかいう用語は使わない方が良い
ポインタのポインタ(たまにポインタの配列)
配列のポインタ
のどっちかにしろ void my_free(void** ptr) { free(*ptr); *ptr = NULL; }
.......
char *data = malloc(size);
.......
.......
my_free(&data);
/* これ以降 data = NULL になってるから参照するとヌルポになる */ >>590
なんで?
double pointerも十分すぎるくらい市民権得てると思うけど。 >>594
char pointer と double pointer が並んでも? 自分がそう呼ぶかどうかはともかくとして、
ダブルポインタやdouble pointer でググればわかるようにそう呼称されることも大変多いわけだから
ポインタのポインタをダブルポインタと呼ぶことが多いことを知らんでいるわけにはいかんのが現実 **ダブル ***トリプル ****クアドラプル?
うーん 使うのはポインタのポインタまでにしとかないと書いててワケわからなくなるぞ 素朴な疑問だけど、ビット演算の | と論理演算の ||
前者を「オア」と呼んで後者を「ダブルオア」と呼ぶ? >>600
|| は論理演算子の「論理or」
| はビット演算子の「ビット or」…あまりそういういいかたはしないような気もしますが ダブルポインタの流れで気になったのよね
言葉だけの疎通で どう言ってたかな?と
※ 「ビットor」 「or」 後者は前後の文意で汲んでくれ のような使い方してるわ 明示的にビット毎のorを指すときは bitwise or と書くけど日本語ではなんていうんだ
教科書なら「ビット毎の論理和」でいいんだろうけど古臭い
声に出して読むときは2つ組みの方をオアオアとかアンドアンド >>604
世間で使われてる用語を使わず「理屈で言えばこうだ」と
勝手に言葉を作ってると造語症と思われるぞ double linked list のdoubleは行きのポインタ(リンク)と帰りのポインタでdoubleだし
日本語より論理的と言われがちな英語も割といい加減だよね
日本語では双方向リストと実に論理的な呼称 いや double pointer, triple pointer と増やしていけるし数学的なのかな
これ式で日本語でたまに使われるのは2重(2段)ポインタ、3重ポインタか >>603
JIS だと「ビット単位のOR演算子」と「論理OR演算子」と書かれている。
あくまで訳語のひとつでしかないけど、JIS の性格を考えれば公式訳と言ってよかろ。
| と || の代替表記として bitor と or があるので、発音するときはこれでいくのもアリかもね。 二重ポインタを思わず「ハンドル」と言ってしまって怪訝な顔をされる俺。 C99 をざっと見た感じでは double を指すポインタは "pointer to double" という書き方になっているけど、
カジュアルな場面で double pointer と言わないとも言い切れないだろうし、
これについては >>595 の言い分に説得力を感じる。
英語がよくわかる人の肌感覚ではどんなもんなんやろね? ポインタへのポインタでしかないもんを
ダブルポインタと言い換えるの気味悪い だからな
ただの変数だからな
ただのポインタも例外じゃない >>607
doubly linked list じゃね?
https://books.google.com/ngrams/graph?content=double+linked+list%2Cdoubly+linked+list&case_insensitive=on&year_start=1800&year_end=2008&corpus=15&smoothing=3 >>613
お前さんの感覚なんてどうでもいい
pointer to pointer c でググると
Double Pointer (Pointer to Pointer) in C
https://www.geeksforgeeks.org/double-pointer-pointer-pointer-c/
が最初に出て来る現実を見なよ おまえら、本当の0からの初心者にも、やさしくしろよな。 初心者だから何でも許されるというのは間違った考え
安田はジャーナリストとしては初心者
無能に仕事を任せるのは損失 むしろ無能を起用した側の責任も
ジャーナリストは自己だが >>619
そういうお前が一番の初心者じゃねえのかw プログラム全体でただ1つだけ走らせることが出来る、ある機能を提供するライブラリを作りたいんですけど
シングルトンで実装するのが一般的なんですかね よくわからん それただのcの関数やんけ
staticのメンバ関数で十分 スレッドの数なのか変数の数なのか
なんでライブラリがそんなことを強制せにゃならんのか よくわからん状態で作って、システム停止状態になる予感 >>819
そんな考えだったら、スレタイの、【初心者歓迎】をはずせ。 >>819
>絶対許さない
え、どういうことですか? vector<int> v{1, 2, 3, 4};
と定義して &v[0] からのバイト列にアクセスすると
01 00 00 00, 02 00 00 00, 03 00 00 00, 04 00 00 00
と連続して確保されているようですが
●これは仕様上保証されていますか?
また
vector< vector<int> > w{{1, 2}, {3, 4}};
と定義して &w[0][0] からのバイト列にアクセスすると
01 00 00 00, 02 00 00 00, ?? ?? ?? ??, ?? ?? ?? ??
後半がランダム?
になるようですが
連続に
01 00 00 00, 02 00 00 00, 03 00 00 00, 04 00 00 00
と確保されるように2次元のvectorを定義するにはどうすれば出来ますか?
それとも出来ないのでしょうか? >>632
エンディアンもintサイズも固定じゃないので保証されない vector の連続性について
ttp://cranehouse.dojin.com/program/vector.html
ttps://www.wdic.org/w/TECH/std::vector#xE3x83xA1xE3x83xA2xE3x83xAAxE3x83xBCxE3x81xAExE9x80xA3xE7xB6x9AxE6x80xA7 vectorには本体データの他に管理データもあったりするので
そのvectorを作ると間にゴミに見えるデータが入りうる ありがとうございます
int (*hoge)[要素数]; じゃなくて
int *hoge[]; みたいにポインタの配列になってるということでしょうか? w[0] が返す vector の次元(大きさ)と
w[1] が返す vector の次元(大きさ)は異なっててもいい
から、そもそも論で 2次元配列 とは等価にならんし 前者だと要素追加しようとしたらどんちゃん騒ぎだよね >>632 >>640
array< array<int, 2>, 2 > w{ {{1, 2}, {3, 4}} }; 適当なラッパーを作って
期待する形のバイト列にするイテレータをくっつける
とかいった方法が考えられるかなぁ。
まあ場合によるけど、
大きさがコンパイル時に確定してよいのなら、
>>641 の方式が確実だと思う。
多次元配列を作る場合ってほとんどの場合はコンパイル時か
オブジェクト構築時には大きさが決まってると思うんよね。
後から伸ばしたり縮めたりってあんまりしなくなくなくなくない? 1次元での連続性の要求は理解できるけど、2次元以降の多次元で配置の連続性の要求って何処からきてる?
思い浮かぶのが画像データぐらいだけど、それなら1次元+演算でも代用可能だし… 2次元配列状のデータを2次元ベクタに一発で流し込めるからじゃない? 環境に関して質問です。
windows10でcの環境作りたくて、コンパイラにminGWを入れたのですが、実行時エラーがでなくて不便です。
例えば、
char c='x';
printf("c: %s",c);
のように出力時のフォーマットを間違えたら、LinuxではRuntime error〜となにかしらエラーがでていたのに、エラーも何も出ずに(c: すら出ないで)終了します。
minGWの仕様なのか否か。
または、
windows10でminGWを使い、実行時エラーを出す方法を教えてください。 >>645
言語仕様的には未定義なので、実行した結果がどうであっても言語仕様通り。
ランタイムに捕捉できることを期待しない方が良いと思う。
C/C++ っていうのはそういうもんだから。 >>645
minGWを使ったことないんで間違っているかも知れないが
GCCならGDB使えば実行時エラーを捕捉出来るんじゃないか? >>647
gdbで捕捉できるんですが、gcc実行のみでRuntimeErrorを表示させるにはコンパイラ変えるしかないですかね?
もともとvmにLinux入れて、c言語を学ぼうとしてた初心者の集まりなんですが、vm重いからwindowsに移行しようと、環境設定が簡単な方法をいろいろ試してるところです。
なので、Linuxでできてたことができなくなることが不安という感じです。 >>648
例えば、GCCの代わりにVC使ったとしても
エラーを捕捉出来るかどうかは分からないよ
どちらかと言えばOS側の仕様な気がするし たまたまアクセスしたアドレスがアクセス違反でもない限り、そもそもエラーにしようがない気がするのだけど、どうやって補足してるの? 多分リンクするランタイムライブラリ側の仕様ではないかと >>645
エラーレベル上げるとかそう言うフラグがコンパイラに無かったかな?
その初期値が違ってるだけじゃ無いの? あ、実行時か。
Cは実行時エラーの処理も自分で補足して書くものよ?
そう言う言語としか言えない。 不定や未定儀を自らトラップするコードを記述するのは難易度高いな… 例外が捕まれば御の字だが アドレスが 0 付近のページはプログラムミスでアクセスされやすいってことはわかっているので、
Windows でもなんか特別に予約してたような気がしたんだが、手元の資料で見つからんな……。 MMU付きのシステムなら、0番地をTLB missさせるのは一般的だね
けど、これ見るとwin95は違ったみたい。winNTはそうしてたみたい
Why is 0x00400000 the default base address for an executable?
https://blogs.msdn.microsoft.com/oldnewthing/20141003-00/?p=43923 0番地ってNULLポインタ値に割り当ててなかった? >>657
NULL はあくまでも「無効なポインタ」を表し、意味のある番地ではない。
けど、うっかり意味のある番地としてアクセスしたら 0 番地だから、
その付近へのアクセスがあったらたぶん駄目なプログラムとして検出しようねっていう話。 今回の場合は char をポインタとして解釈してしまった場合ってことになるけど、
(0 ではないが) 0 に近いアドレスなので、その付近のページは
トラップ用に予約しておいたらあかんプログラムの検出に便利やんというわけ。 本筋とは関係ないけど念のために補足しておくと、ヌルポインタがゼロというのは、
そういうアーキテクチャがほとんどだと思うけど言語仕様の保証はない。
整数のゼロと互換性はあるという扱いで、
つまりは、ヌルポインタを整数にキャストするとゼロだし、
ゼロをポインタにキャストするとヌルポインタになることは保証されるが、
ヌルポインタのビットパターンが整数のゼロと等しいことは保証されない。
(なので移植性が必要ならポインタの配列を memset とかで初期化したりするのは駄目) >>ゼロをポインタにキャストするとヌルポインタになることは保証されるが
そうだっけ。定数のゼロだけでは? >>661
そういや C++ ではそういう変更もされたような気がするな。
以前は確かに定数に限らずゼロはヌルってことだったはずだが。
C では今でもヌルはゼロ (と相互に変換される) だと思う。 >>661-662
リテラルの 0 じゃなきゃダメなように改められたのは C++14 からだった。 >printf("c: %s",c);
va_list な関数でフォーマットからパラメータの妥当性チェックって
コンパイル時に出来るもんなのか? コンパイル時にprintfのフォーマットチェックくらい出来る >>664
標準ライブラリ関数みたいに、コンパイラ作成時点で仕様が確定してれば可能。
https://wandbox.org/permlink/d1F80sYjt6FhgjY8
> prog.cc:5:19: warning: format specifies type 'char *' but the argument has type 'int' [-Wformat] 逆に言えばコンパイラが特別扱いする必要があるってことだね。 面倒なので出力書式には%sのみを使うこととし引数の型の分だけstringに変換する同名関数用意して必ず文字列にしてしまうという力技 >>669
オブジェクト指向的にはそれが正解なんだよな >>669
まあ結局どこかで文字列化するんだからその考え方もありだね cout << left << hex << showbase << setfill('0') << setw(8) << i << eol;
より
cout << i.tostring("0x%-08x") << eol;
とかなら %書式 にはあまりこだわらないんだけど
前者の仕様だと %書式 の方が描きやすいから
結局普及しない原因 よくint型のサイズとかエンディアンが処理系依存って解説を目にしますが
この「処理系」ってコンパイルするマシンのCPUですか?
それともプログラムを実行するマシンのCPUですか? >>673
コンパイルするプログラムや出来たプログラムを実行するOSやハードウェアなどの諸々の環境 ターゲットになる処理系にあわせてコンパイルするからな
べつにターゲットになる処理系でコンパイルする必要はない ありがとうございます
ちょっとプログラムを見直してみます >>673
CPUで変わるのはもちろんだが
クロスコンパイルも可能なので
コンパイル時のオプションでも変わる constexpr char *mes[] ={(char *)"error", (char *)"ok" ,(char *)"abc"};
みたいにキャストしないとワーニングがでるんだが、めんどくさいね。なんか方法ないの? constexpr const char *mes[] ={"error", "ok" , "abc"};
constexprが何にかかっていたか考えてみれ constつけたらワーニングが無くなるのだろうか? 何故なくなるの?
ポインタにかかるのか、ポインタの中身にかかるのか?という問いだろうけれども恐らくはポインタ自体
にかかるのだろう。そしてconstがポインタの中身にかかる。順番が逆だといろいろ不都合がしょうじる
から、このようになる筈だ。
しかし、constを追加しただけでwarnningが消える理由はなんなのだろうか? (char*)でキャストするのと
同じ効果を持ちうるのはなぜか? constにはそんな意味はない。「単に書き換えできないようにする」
と言う意味だろう。書き換えできないsringももちろんあるから矛盾が生じるのだ。その矛盾を
解決する可能性があるとすれば書き換えできないstringがすなわちchar*と同じである場合に限る。
つまり
const string とは char* の事なのだ。
あってる?
もしあってるとすれば、
constexpr (char*) char *mes[] ={"error", "ok" , "abc"};
でもOKな筈だね。そうでないと矛盾する。この方が分かりやすいね。 そしてワーニングはすべてきえたが、エラーになった。w constexpr const char *mes[] ={"error", "ok" , "abc"};
これをクラスのなかで定義したいのだが、クラスの中で定義するとエラーになる。クラス内だけで使いたいのに
外部に引き出すのは面倒だ。どうしたらいいの? >>681
書いている意味はさっぱりわからんが、文字列リテラルの型は const char[] だ。
そんでもって >>679 の場合の文字列リテラルは暗黙の型変換で const char* になる。
const char* を char* に入れようとしたら型が合わないがキャストで無理やり合わせることも出来るという簡単な話。
だが、型から const を剥がしたからといって文字列リテラルを書き換えてよくなるわけではない。 (← 重要!)
const を剥がすだけなら問題はないが、
書き換えたら駄目 (未定義) にもかかわらず型から const を外すのは馬鹿馬鹿しい間違いの元。
よくわからんままキャストしたら警告が消えた〜〜っていうのはC/C++ の歴史で何十年も繰返してるので
古参ならうんざりするほど見てきた駄目なパターンだと思う。
とりあえずキャストってのはほんとにやめて……。
(ちなみに C では文字列リテラルの型は char[] だが、書き換えるのは未定義ってことになってるという更なる闇がある) >>686
カタカナにする時点で元の発音からずれまくりなので×も△も五十歩百歩だろ。 ■ このスレッドは過去ログ倉庫に格納されています