【初心者歓迎】C/C++室 Ver.103【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
2018/07/01(日) 03:44:53.53ID:4MMF8cDN
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります

コードを貼れる所
http://codepad.org/
https://ideone.com/

前スレ
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/
2018/08/18(土) 00:55:50.62ID:9sBD2gG5
高次元だとイメージよりアナロジーが先行するかな自分の場合
立方体より単体のほうがイメージしやすいが
立方体だと[0,1]^nに微分同相とかきっとそんなん
2018/08/18(土) 01:07:54.17ID:gititOy1
>>262
やはりスゴイと言うしかない
そういう人なら、ゴムボールを切らずに裏返しにする事も出来そうだ
勿論、頭の中でだけど
2018/08/18(土) 04:51:32.26ID:bmeyL4DX
>>261
切断wという予測変換に驚き
266デフォルトの名無しさん
垢版 |
2018/08/18(土) 16:12:57.62ID:sAtTg2RR
>>239
√2は手続きではないだろう。
1に1を足した数に2ってラベルがついてるのと同じで、
(√2)^2=2となるような無理数にラベルがついてるだけ。当然2の平方根に完全に一致する。
そして誤差のオーダーを必要とする時点で近似的な取り扱いしかできないということになるのだから、
√2が必要であれば√2として持つしかないだろう。
10進小数点表記で任意精度で表すためにはその手続きが必要となるだろうけど。
2018/08/18(土) 16:29:04.35ID:H8XUQRKC
2は自然数の加減乗除で表せる(というかそれが定義)けど、ルート2はかけない
じゃあルート2の定義はっていうと、方程式の解であって、1と2の間に存在しそうだけど本当にあるの?って話
結局新しい仮定が必要になってきて、それが収束有理数列と同値で、この列は手続き=関数と同値

なんかスレチで荒らしてすまんな
困難わかってても実際はあまり役にたたたないし
268デフォルトの名無しさん
垢版 |
2018/08/18(土) 17:52:26.48ID:sAtTg2RR
>>267
それは正の数の平方根数が実数上に確かにある存在の証明の手続きでしかないよね
実際に任意精度で√2を求められる関数を使って(√2)^2が2になるか確認するには無限の時間がかかるよね
正の数の平方根数が実数上に確かにあるという前提に基づけば単に√2は(√2)^2が2になる性質を持った無理数、
といった形で取り扱えば十分だし、「√2は手続きだ」は言い過ぎじゃないかな。
それを言い出したらほぼ全てが手続きになってしまう。「数学的に同値」というのは「√2は手続きでも表せる」ってだけでしょ。
269デフォルトの名無しさん
垢版 |
2018/08/18(土) 19:07:39.30ID:Ruc+zSzi
>>264
4次元の立方体なんてイメージとしての意味をなさないだろ。w というか各辺が4mの
4次元立方体なら「各辺の長さ=4m」且つ「各々の辺が互いに直行する」というだけの話だから、
Leng(a,b,c,d) =(4,4,4,4)
cross(a,b) =true ; cross(a,c,)=true:  cross(a,d)=true;
ってことだけだろ。
性質として体積は4^4 とか表面積は=ん?になるとか
一寸考えれば誰でもイメージを膨らませることはできる。
2018/08/18(土) 19:51:41.56ID:gititOy1
>>269
一応ね、
4次元超立方体同士がすれ違うときに
接空間を頭の中に描けるかどうかかな
さらにそれらが自転していたらどうかとか
2018/08/21(火) 20:26:27.42ID:3mimrG+c0
モダンなC++はnewしたのdeleteしなくても自動でやってくれるって聞いたけどガセ?
ちゃんとスマポ使わないと漏れますよね?
2018/08/21(火) 20:29:13.48ID:H0lJZ+G5
ガセっつうか、ウソだよな。
2018/08/21(火) 20:33:14.11ID:oNgzJjko
輝くトラペゾヘドロンかすれ違い
2018/08/21(火) 20:33:53.94ID:Rfqd4rGm
プロセス終了させたときにdeleteされるとかそんなオチ
デストラクタが走らないからそれもないか
2018/08/21(火) 20:34:16.90ID:FuTngql1
>>271
プロセスが消える時に全て消える
2018/08/21(火) 21:21:07.83ID:2u+Qiv0I
スマポとGCの違いって何さ
2018/08/21(火) 22:33:32.03ID:r2zII1ha
newしたポインタはスマポで管理して自分でdeleteを書く必要がないっていう話が
文章読めない人の中でねじまがったんだろ
2018/08/21(火) 22:52:47.19ID:H0lJZ+G5
スマポは自分でメモリーを管理するが、GC方式は管理をGCに任せる。
2018/08/30(木) 06:57:53.59ID:kCgj5iLA
入門書ロベールで使い方の説明もなくunsigned charという型をでキャスト演算してるのですが
unsigned charはcharより沢山文字が格納できる型ってことであってますか?
またsize_tは整数型ってことであってますか?
2018/08/30(木) 07:13:58.56ID:Hf5mdE4J
>>279
合ってない
2018/08/30(木) 07:23:29.48ID:kCgj5iLA
あってないですか..
ロベールにもろくに説明ないので弱りましたね(+_+)
Size_tはアドレスを整数値に直すのに使ってたり関数の戻り値に使ってる例題があったので
整数を表すなにかと思ってたんですが違ってます、か

ググってみてもイマイチ分かりません
https://www.wdic.org/w/TECH/size_t
2018/08/30(木) 08:43:34.49ID:GbaSH31o
ロベールって人の本は読んだことない(ネット公開版は少し見た)けど、
もっと先に進めば unsigned の使いどころとか size_t の説明とかが
詳しく載ってるって構成じゃないの?
この時点でコードの細かい部分まで理解する必要はない、てな感じで。

疑問は疑問として(忘れずに)保留しておいて、とりあえず読み進むのも手かと。
2018/08/30(木) 08:53:18.15ID:kCgj5iLA
char ch='C'
cout<<(int)(unsigned char)ch<<endl;
これは何をやってるコードなんですか?キャストって2つ一変に使えるんでしょうか。
特にコード自体に意味はなく文字は数字で表現されてると伝えたかったんでしょうか?
ロベール入門は章の冒頭から応用みたいな例題出すから意味がわからなくなります
2018/08/30(木) 09:21:44.13ID:84fjp1F/
符号つき整数や符号なし整数のビット表現とかわかってないと、難しいんちゃうか?
2018/08/30(木) 12:59:10.03ID:8c0RjkhV
でも、言語仕様的にはビット表現に関する規定ってあんまりないんよね。
未定義な部分や処理系定義な部分もあるので、
ビット表現で考えていたら言語仕様的には実は未定義みたいなのに引っかかってそれはそれでぐぬぬぬぬってなることもある。

char については歴史的事情でややこしいのは確かだと思う。
char が符号付きか符号無しかは処理系定義だが、
char が符号有りだったとしても符号無しだったとしても signed char とも unsigned char とも違う独立した型になっている。

>>283
char が符号付きとして定義されていた場合に int にそのままキャストすると符号拡張されるから、
それを抑制するためにいったん unsigned char を経由したのではないかと考えられるが、
入っている値が 'C' であることが確定しているならば負数ではない値で表されることは保証されているので、
unsigned char にキャストする意味なく、いきなり int にキャストしても結果は同じ。
2018/08/30(木) 16:08:50.62ID:GbaSH31o
charの変数chを(ASCII文字でなく)1byteの数値を格納するために使う場合、
単なるcharがsignedかunsignedかは処理系依存だから、
変数に格納された値を正整数(一般に0-255)としてダンプしたいときは
いったん unsigned char にキャストしてから int にキャスト、
すなわち (int)(unsigned char)ch と書くのが確実であり良い習慣である。
……てな感じかなぁ。おそらく初心者にはサッパリ分からないだろうけど。

static_cast<int>(static_cast<unsigned char>(ch)) じゃろとか
そもそも 0-255 の範囲の数値なら unsigned char で変数宣言すべきとか、
ツッコミどころも色々あろうが、きっと後のページで説明されるよね。
2018/08/30(木) 16:35:06.48ID:nDsa3YKs
unsigned charに変換しとけば
intには勝手に変換される
2018/08/30(木) 16:45:57.86ID:GbaSH31o
>>287 いや、その点は試したんだ。俺の環境では…

char ch = 'C';
cout << (int)(unsigned char)ch << endl; // 67 と表示される
cout << (unsigned char)ch << endl; // C と表示される

少なくとも unsigned char が必ず int に変換されるとは言えない。
自動的に変換される処理系もあるかもしれんが、それはそれ。
2018/08/30(木) 17:36:17.31ID:8c0RjkhV
>>287-288

>>283 のケースで int への明示的キャストを外すと int へは変換されない。

std::operator<< がいくつかの基本的な型に対応するようにオーバーロードされている内には
unsigned char のシグネチャを持つものも用意されているので、
unsigned char 型の引数が与えられればそのままマッチする。

変換が挟まる余地はない。
290286 == 288
垢版 |
2018/08/30(木) 17:37:27.96ID:GbaSH31o
たびたび失礼。
「試すんじゃなくて規格でどう動くべきか語れ」と言われればその通りだけど、
俺の能力を超えているということで。より有能な人の援護を期待。
2018/08/30(木) 23:00:44.23ID:kCgj5iLA
>>282->>285286
ありがとうございます
せっかく回答貰ったのですがunsigned charがどういう型なのかとかそういった説明が
本書で無いのでやはり何度読み返しても理解できませんでした
今は文字を符号なしの整数に直すおまじないってことで覚えておこうと思います
292デフォルトの名無しさん
垢版 |
2018/08/30(木) 23:14:11.82ID:/0YXnEsV
まず補数についてお勉強しなさい
まずそっから

そしてそれを8bit、16bit、32bitで表現するとどうなるか
考察しなさい

わかった?
293デフォルトの名無しさん
垢版 |
2018/08/31(金) 00:08:27.43ID:4ZfpOo1s
https://ideone.com/gFxr1T
どっかから拾ってきた関数のソース(なんかのlibcのソース)をコピペして
signed charとunsigned charの2進表現をダンプしてやったから
補数のお勉強が捗ったら、あとで参考にしなさい
2018/08/31(金) 00:18:16.04ID:NWzNDPzW
繰返すが、言語仕様上はビット表現についてたいした決まりがあるわけではない。
表現できる範囲に着目した方が理解しやすいんでないかなぁ。
295デフォルトの名無しさん
垢版 |
2018/08/31(金) 00:19:55.81ID:4ZfpOo1s
決まりがなかったら
ビット演算なんかできない

バカのいうことなんか
ほっといていいからな
2018/08/31(金) 00:26:44.11ID:NWzNDPzW
実際に決まってないもんは決まってない。
1 の補数を使うようなのも許されるし、実際に存在する。
ポータビリティに配慮しなければなんでも出来るのが C/C++ の良いところだが、
ガチで規格を把握しようとすると未定義の罠だらけなんよな。
297デフォルトの名無しさん
垢版 |
2018/08/31(金) 00:27:45.45ID:4ZfpOo1s
きっとバカのオツムでは
リトルエンディアンとビッグエンディアンの計算機では
ビット演算の結果がかわる

もしくは変わるようなクソみたいなコードを書く
もう察しがつくのが怖いわ。。。
2018/08/31(金) 00:30:09.11ID:NWzNDPzW
少なくとも >>293 の結果は言語仕様的に保証されない
299デフォルトの名無しさん
垢版 |
2018/08/31(金) 00:42:21.23ID:4ZfpOo1s
uint32_t aho;
unsigned char* baka = (unsigned char*)&aho;

知恵遅れはこんなことを平気でする
そして計算機によって結果がかわっておかしいおかしいとかいうワケ
2018/08/31(金) 01:19:33.15ID:NWzNDPzW
関係ないことに話題を広げないでくれよ……。
2018/08/31(金) 01:29:11.81ID:NWzNDPzW
数値のビット表現に2の補数が使われるとは限らないってだけの話な。
2018/08/31(金) 06:31:48.92ID:Df6BGOL7
>>292
キャストの必要性と負の数の内部表現は全く関係ないように思うけど
2018/08/31(金) 06:35:22.71ID:Df6BGOL7
負の数の内部表現は
少なくとも以下の3種類は存在する

1の補数
2の補数
符号ビット

マイナスゼロはトラップ値として使ったりする
2018/08/31(金) 08:21:09.97ID:kqLurM/K
https://ideone.com/ub97A1
すいません↑の29行目のコードって何してるんですか?
int size = sizeof student / sizeof *student;
sizeofで studentと*studentが3に化けて 3,3で割り算して1じゃないんですか
意味がよく分かりません;
2018/08/31(金) 08:43:55.47ID:CKe+Ima+
>>304
配列の定義が見えてる場合 "sizeof 配列名" は配列全体の総バイト数になるのよ。
対して "sizeof *配列名" は "sizeof 配列名[0]" と同じで配列要素1個のバイト数。

配列全体のバイト数 / 配列要素1個のバイト数 == 配列の要素数
配列の要素数を知るためのイディオムだな。

ちなみに sizeof student も sizeof *student も 3 にはならないと思うよ。
むしろ sizeof student / sizeof *student の計算でようやく 3 が得られる。
2018/08/31(金) 08:48:39.35ID:B6cJ6E2C
>>304
配列の要素数を計算しているかと
sizeof studentは、配列のバイト単位の長さ
sizeof *studentは、student型のバイト単位のサイズ
2018/08/31(金) 10:31:41.89ID:kqLurM/K
>>305-306
これ割り算じゃないんですね
なんとなく理解できました。ありがとうございます
この方法を使うと配列が増えてもループのとこ書き直さなくてもいいということですか
2018/08/31(金) 11:51:09.55ID:B6cJ6E2C
>>307
割り算だよ
バイト単位で配列のサイズ(個数)を算出しているだけ

>この方法を使うと配列が増えてもループのとこ書き直さなくてもいいということですか
そう
2018/08/31(金) 18:49:29.63ID:NWzNDPzW
>>302
そう。 キャストについてはビット表現は関係ない。
だから (規格ではっきり決めていない) ビット表現を中心に理解しようとするのは余計なことだっていう主張ね。
2018/08/31(金) 19:17:02.43ID:CKe+Ima+
でも具体的なビット表現、0か1がいくつか並んだものを見せて
「符号なしなら数値として〜、2の補数表現なら〜と解釈される。
それを符号拡張なりゼロ拡張なりすると…」
という具合に教えた方が理解は容易な気がするよ。

「規格では(値の範囲は決まっているが)ビット表現は決まっていない」の
一点張りで、抽象的な説明だけをしても分からんでしょ。

とりあえずcharは8ビット、負数は2の補数表現、のモデルで
話が飲み込めれば、その先のcharが8ビットじゃない処理系や
負の数の表現方法が異なる場合に進める。
どうせ大半の処理系は8ビット・2の補数だから無駄にもならんし。
8ビット・2の補数に凝り固まることのないよう、気をつけて教えるってことで。
2018/08/31(金) 20:21:33.49ID:NWzNDPzW
>>310
俺も先にアセンブラを触ってたタイプだからビット表現からの理解をしたのでそれが自然なんだけど、
0 と 1 の集まりで表される世界が、
表現範囲が決まっているという考え方よりも感覚的にわかりやすいだろうかと冷静に考えると
一般的にはそうでもなくない? って思えてるってのもある。

レイヤを分けて考えるってのはそんなに簡単ではないよ。
「コンピュータの中でこう処理されている」というのを知った上でそれを忘れて (抽象の壁の向こうに追いやって)
「言語の考え方 (規格) ではこうなっている」という理解を持てるかどうか……。

どうせ C を使ってるとやっぱり現実のコンピュータが透けてみえちゃうんだから、
「言語の考え方はこう」というのを押さえておけば
あとは自動的に「それを実現するために内部ではこうなっている」という風に理解していけると思うんだがなぁ。
2018/09/01(土) 00:56:02.54ID:8bxP8UXu
>>311
具体的なものがあるからこその抽象化じゃないの。
抽象化したものだけでは具体的に動かすことができないから理解するのは難しいでしょ。
2018/09/01(土) 01:29:32.00ID:0H62RJv3
>>312
アセンブラの色々を自動化したみたいな立場からのスタートだから、
歴史的には具象から抽象へという形で成立しているが、
あくまで C を学び始めた人のスタート地点として、
「ビット表現、あるいは範囲が決まった値のどちらがなじみやすいか」という話。

普通の人が日常的に数値を扱うことはあるし、
その中には上限・下限が決まっているということもある。
でも、 0 と 1 の集合で表現するという考え方を日常的にしている人はかなり少数派だよ。
馴染みやすい方から入って行って最終的に「なるほど内部ではこう表現されるのか」
に至るのってそんなに不自然な道筋かな?
2018/09/01(土) 11:33:31.89ID:8bxP8UXu
>>313
だから具体的に動作させられる環境がないと勉強出来ない。
小学校で1+1を学んで中学でx+yのように抽象化してきたでしょ。
2018/09/01(土) 13:35:02.88ID:0H62RJv3
>>314
数値型変換の規則とかも数値として決まってる。
動作させるのにビット表現で考える必要は無いだろ。

なんらかのビット表現を割り当てて動作はするけど、
そりゃコンパイラの考えることで、
人が最初からどうしても把握しておかなきゃならないもんではない。
2018/09/01(土) 14:58:35.23ID:lb2h//8s
>>315
ビット表現を最初から考えておく必要も把握しておく必要もないけど、具体的な実体を知っていた方がイメージしやすく理解しやすいと思う。
そこまで忌避する理由が分からない。
2018/09/01(土) 15:48:37.66ID:GfEkw2/x
多倍長計算涙目
318デフォルトの名無しさん
垢版 |
2018/09/01(土) 16:37:00.14ID:/wwW4VSs
頭悪いからビット演算できないと自白してる
2018/09/01(土) 16:46:00.86ID:0H62RJv3
>>316
繰返すが、数値のビット表現は世間一般の感性からすると全く異質だ。
だから「(いきなり最初には) イメージしやすくない」と言ってるの。
無理してでも最初に身につけられたら後が楽ってことはあるかもしれんが、
イメージしやすいってことは無い。

ビット表現は C に慣れた人にとってあまりにも当然の大前提すぎて、
それをわからん奴にはだいぶんイラつくが、
すんなりとは納得できない方が普通だよ。
320デフォルトの名無しさん
垢版 |
2018/09/01(土) 16:47:02.21ID:/wwW4VSs
はいはい
頭悪いからビット演算できないと
だからどうした
2018/09/01(土) 16:50:28.48ID:0H62RJv3
>>318
入門者の大多数が (十分に) 頭が良いと想定するのはそれこそ馬鹿げた判断だ。
とんでもない方向の思い違いが勢ぞろいなのが普通。
322デフォルトの名無しさん
垢版 |
2018/09/01(土) 16:56:01.26ID:/wwW4VSs
健常者に届かないぐらい頭悪いから
オレはビット演算はあきらめた
と自白されても困るワケ
2018/09/01(土) 17:10:11.60ID:3YNLHjk8
外野から見ると自分は頭が良いと思い込んでそうなID:/wwW4VSsよりはちみつの方が賢そう
324デフォルトの名無しさん
垢版 |
2018/09/01(土) 17:11:33.86ID:/wwW4VSs
オレは頭いいとか
ひとことも書いてないからな

キミラが健常者に程遠いほど
頭悪いわけ

それがわからない?
325デフォルトの名無しさん
垢版 |
2018/09/01(土) 17:12:36.29ID:/wwW4VSs
まず途方もないほど頭悪いという自覚がない
それが致命的

バカを自覚できないからバカが治らない
2018/09/01(土) 17:14:33.25ID:np0z0HoI
はちみつさんの主張「初心者にビット表現から教える必要はない」を
当人がビット演算できない僻み、とか捉えるのは明らかに間違いだろ。
対立が昂じて厳しい言葉を使いそうになった場を茶化すのは俺も好きだけど。
(余計に険悪になったところで「お呼びでない…」と立ち去る流れまで込み)

実際のところ「初心者に2進数での数値表現を理解させることが困難か?」
については、今なら「コンピューターの中ではゼロイチで情報が記憶される」
くらいの基本知識は持ってるだろうから、昔よりは敷居が低いんじゃないかな。

…とは言え自分もマシン語ハンドアセンブル相対ジャンプ暗算から
入ったクチだから、経験に基づいたバイアスが強いかも知れん。
ビット表現を使わず初心者に説明する良い資料があるなら読んでみたい。
たぶん得るところは大きい。
2018/09/01(土) 19:35:38.40ID:iulr/33e
"はちみつ餃子"でググってもそういうのが出てこない…
2018/09/01(土) 20:41:28.08ID:V3Jbt1LZ
>>326
必ず半角カナを使ってレスしてるいつもの人は、常に持論は正しく相手は低能というスタンスで一方的に断定しかしないから、深く考えても仕方ないよ。
半角君のいってることはまともなこともあれば的はずれなこともあるけど、常に共通するのは周りの指摘や疑問には耳を貸さず、議論の流れも無視して自分の主張を繰り返すだけということ。
だから、斜め読みして受け流すだけでいいと思うよ。
329デフォルトの名無しさん
垢版 |
2018/09/01(土) 20:56:42.17ID:/wwW4VSs
なるほど
知恵遅れは議論したつもりになってんのか
知恵遅れの場合議論できるレベルに到達してない

まずそこの自覚がない
2018/09/01(土) 21:11:37.01ID:DoChZsV8
C形式の二次元配列は先頭から一次元配列みたいな顔して普通にアクセスできると思うんですが
C++11以降でネストしたstd::arrayでもポインタを使って一次元配列のようにアクセスしても規格上セーフですか?

↓のコードのようにforループ一つで上下左右方向の繰り返しを済ませたいです
https://ideone.com/HbRfZu
331デフォルトの名無しさん
垢版 |
2018/09/01(土) 22:08:01.79ID:/wwW4VSs
1次元の可変の列を行とみなして
そのそれぞれの行に可変の1次元の列がある状態になってる

つまり、行毎にバラバラにそれぞの行のヒープができる作りになる
そもそもC++の規格とか関係ない

低学歴であれば低学歴であるほど
言語の規格なんかぜんぜん分かってないくせに
自分を大きくみせるために言語の規格がどうこういってるのだけは
よおく分かったわ
332330
垢版 |
2018/09/01(土) 23:53:24.94ID:DoChZsV8
>1次元の可変の列を行とみなして
>そのそれぞれの行に可変の1次元の列がある状態になってる
>つまり、行毎にバラバラにそれぞの行のヒープができる作りになる
というのはどういうことでしょうか
行ごとにバラバラなので行をまたいでのアクセスはできないという意味でしょうか

C形式の多次元配列もネストされたstd::arrayも、各要素は連続したメモリ領域に置かれていますよね
というかC形式の(少なくとも)二次元配列は一次元配列として全要素にアクセスできると思っていたのですが
間違っていますか?
333デフォルトの名無しさん
垢版 |
2018/09/02(日) 00:08:35.47ID:Tb3tt8fk
array 1個作ったら1個ヒープできるのはわかる?
2018/09/02(日) 00:20:34.44ID:vK23Frpo
>>326
昔から C を使っている人ってまさにそういう感じの低レイヤや
それに付随するあれこれの知識と一緒に習得してきた人が多いと思う。
だけど、 Teratail とか StackOverflow とかでの質問を見てると、
俺らがあまりにも当然の前提と思ってそこにあることにすら気づいてなかったものが
今の入門者にとってはハードル高いのかもしれないと感じることが結構あって、
教え方も昔の通りにはいかないんじゃないかねと思えてるの。
2018/09/02(日) 00:23:28.95ID:PYGLVvbR
>>330
Cでも未定義動作だよ。
JIS C (JIS X 3010:2003) 6.5.6 加減演算子
>  整数型をもつ式をポインタに加算又はポインタから減算する場合,結果は,ポインタオペランドの型を
> もつ。(中略)ポインタオペランド及びその結
> 果の両方が同じ配列オブジェクトの要素,又は配列オブジェクトの最後の要素を一つ越えたところを指し
> ている場合,演算によって,オーバフローを生じてはならない。それ以外の場合,動作は未定義とする。
2018/09/02(日) 00:24:09.91ID:fnBlw2CS
>>334
それって単にプログラミングをする人の増加の問題では
337デフォルトの名無しさん
垢版 |
2018/09/02(日) 00:26:27.09ID:Tb3tt8fk
バカは自分で引用してる文章の意味がわかってない
ホントなかわいぞうなぐらい頭悪い
338デフォルトの名無しさん
垢版 |
2018/09/02(日) 00:27:46.09ID:Tb3tt8fk
バカはなんでとてつもなく自分がバカであるか
分かることは永遠にない
2018/09/02(日) 00:34:24.38ID:7WdK6EV6
>>333
mallocしないとできんのじゃないの?
Cだし
340335
垢版 |
2018/09/02(日) 00:36:08.13ID:PYGLVvbR
>>330
ごめん引用元のURL貼り忘れてた。
http://kikakurui.com/x3/X3010-2003-01.html
2018/09/02(日) 00:42:46.41ID:eH7Ohm4T
>>333
ヒープというのは動的に確保されたメモリのことでしょうか
ネストしたstd::arrayというのは、std::array<std::array<int, 2>, 3>というような意味で使っていました(リンク先のコードにある通り)
その場合メモリは動的確保されないと思いますが…

>>335
Cのその「配列オブジェクト」というのは多次元配列を一つのオブジェクトとして見るのではないということですか
ポインタと要素数を引数にとる関数に多次元配列を渡すコードをこれまで少なからず見てきた(教えられた)から勘違いしてたかも
342デフォルトの名無しさん
垢版 |
2018/09/02(日) 00:50:28.37ID:Tb3tt8fk
ヒープといのはオレがウソ書いてた
そのまま書いたら固定で配列がスタックにできる

アホが引用してるのは
あきらかに全然関係ない頭悪いのを引用してる
343デフォルトの名無しさん
垢版 |
2018/09/02(日) 00:54:46.07ID:Tb3tt8fk
array
┣array
┃┣ int
┃┗ int
┣array
┃┣ int
┃┗ int
┗array
 ┣ int
 ┗ int

こうなる
344デフォルトの名無しさん
垢版 |
2018/09/02(日) 01:03:53.61ID:Tb3tt8fk
アホが引用してる部分は

たとえばこんなソースがあった場合、

int* ai_aho[3] = {1, 2, 3}
int* pi_aho = ai_aho;

for (int i = 0; i < 3; ++i, ++pi_aho) {
 *pi_aho = 1;
}

pi_ahoはループを抜けたあと
pi_ahoはソース上適切でないアドレスをさしてるが
こいつを参照しなければ問題ないということが書いてある
2018/09/02(日) 01:18:27.35ID:PYGLVvbR
>>341
int a[N][M] に対して a + i するときの「配列オブジェクト」は要素型 int [M] で要素数 N の配列のこと。
N を超えて加算すると未定義動作になる。
a[0] + i するときの「配列オブジェクト」は要素型 int で要素数 M の配列のこと。
同じく M を超えて加算すると未定義動作になる。

ポインタを受け取る関数に a[0] あるいは &a[0][0] を渡した場合も M を超えて加算した場合は同じ理由で未定義動作になる。
期待した動作をすることも多いだろうけど、信頼性や移植性は損なわれる。
2018/09/02(日) 01:18:43.68ID:7WdK6EV6
おまえのたとえばは前科があるから信用できん
コピペしろコピペ
347デフォルトの名無しさん
垢版 |
2018/09/02(日) 01:20:32.56ID:Tb3tt8fk
(正)int ai_aho[3] = {1, 2, 3};
(誤)ai_aho[3] = {1, 2, 3}

目視で確認した
コレでいける
348デフォルトの名無しさん
垢版 |
2018/09/02(日) 01:23:43.36ID:Tb3tt8fk
な、低学歴知恵遅れはなにも分かってない
まずなにも分かってないのに規格読んで分かったふりしてるのがよく分かる
349デフォルトの名無しさん
垢版 |
2018/09/02(日) 01:25:42.40ID:Tb3tt8fk
低学歴知恵遅れが規格読んでも
規格なんか分かるわけがないからな

そもそも基本的にポインタがどう加算されるかすら分かってないのに
350デフォルトの名無しさん
垢版 |
2018/09/02(日) 01:43:11.24ID:Tb3tt8fk
uint32_t aho[4];
uint32_t* p_aho32 = aho;
uint8_t* p_aho_8 = (uint8_t*)aho;
p_aho32++;
p_aho_8+=4;

どっちのアドレスも同じになる

配列の場合どうなるか
考え方はまったく同じだな
あとはもう分かるハズだ
2018/09/02(日) 04:27:28.97ID:xXZGLywM
ロベール05-09の関数内に引きこもりって章のサンプルコードが長すぎて読めません(3ページ使用)
<algorithm>ってファイルを始めてincludeしてるにも関わらず其れに関して何ら説明ないし…
この章に関しては静的変数はグローバル変数と同じように使えてプログラムが終わるまでずっと同じメモリを参照している
と覚えられれば必要十分ですか?
何か簡単なコードを書いて教えてくれると助かります

よろしくお願いたします。
2018/09/02(日) 06:48:14.86ID:UYvvvhTW
あってるしコードは気にしなくていい
2018/09/02(日) 06:49:15.39ID:p4iMlD/t
例によってロベール著を読んでないし、下のコードはCだけど、
関数内static変数の説明なら、CもC++も変わらんだろう。
(行数節約のため詰め込み・省略してるので良いスタイルじゃない)

#include <stdio.h>

static void in_static(void) {
 static int cnt = 0; /* staticな変数 */
 cnt++;
 printf(" static %d 回目!\n", cnt);
}

static void not_static(void) {
 int cnt = 0; /* staticじゃない変数 */
 cnt++;
 printf("not_static %d 回目?\n", cnt);
}

int main(void) {
 in_static(); not_static();
 in_static(); not_static();
 in_static(); not_static();
 return 0;
}

こんな感じかな。
このコードには盛り込んでないけど、グローバル変数と違って
「関数内static変数には、基本的には関数の外からはアクセスできない」
という性質もある。
2018/09/02(日) 07:47:30.33ID:xXZGLywM
>>353
違う言語にも関わらず書いていただきありがとうございます
実際に実行してみてかなりスッキリしました
自動変数と静的変数の違い、しかと理解できました
関数についてるstaticも気になるところですが読み進めたいと思います
2018/09/04(火) 08:18:27.05ID:bj+tb6HS
char str[]={"aaaaaa","iiiiiiiii","uuuuuuu"};
は出来ないのに
char* str[]={"aaaaaaa",iiiiiii","uuuuuuu"};
が出来るのはなぜですか?
ポインタと配列は密接な関係にあるんじゃないんですか

よろしくお願い致します
2018/09/04(火) 11:38:18.11ID:ClV8CEAe
"aaaaaa" とか "iiiiiiiii" とか "uuuuuuu" がchar*型だから
char型の配列に入れようとしても無理な話
2018/09/04(火) 12:36:40.35ID:f5HJ/2BD
仮に出来たとしてどういう結果になって欲しいのだろう?
2018/09/04(火) 12:51:15.55ID:bz6n3SY3
char str[]={"aaaaaa"};はできる
char str[]={"aaaaaa","iiiiiiiii","uuuuuuu"};はできない
char *str[] = {"aaaaaa","iiiiiiiii","uuuuuuu"};はできる
char str[][9] = {"aaaaaa","iiiiiiiii","uuuuuuu"};ならできる

一番目は長さを指定しない配列変数の宣言で初期化により長さが指定されている。
二番目は{"aaaaaa","iiiiiiiii","uuuuuuu"}は文字列の配列なので変数の型と一致しないためエラーになる
三番目はポインタの配列なので配列の各要素を対応する文字列で初期化できる
四番目は配列の配列なので文字列の配列で初期化できる(ただし要素数の指定は必要)
2018/09/04(火) 14:22:07.00ID:JAXadswE
>>355
前者の[]は、文字の「列」を表すから
後者の[]は、文字列ポインタの「配列」を表すから

charはcharacterの略称、characterは文字、それが複数個集まった列が文字列
列となっているものが根本的に違う
2018/09/04(火) 17:31:45.30ID:bj+tb6HS
>>357
なんかこの違いを仕様で片付けて覚えるのはあまりよろしくないみたいなこと本に書いてあったので
違いが知りたかったです
>>356,358,359
ありがとうございます
文字列リテラルはポインタ型だったんですね
それなら代入出来ない理由も納得出来ます。スッキリしました
2018/09/04(火) 17:48:16.60ID:f5HJ/2BD
>>360
厳密にいえば文字列リテラルの型は配列だよ。 具体的に言えば const char[] ね。
暗黙の型変換で const char* として解釈される場合も多いってだけ。
362デフォルトの名無しさん
垢版 |
2018/09/04(火) 18:01:39.16ID:gZnu4stV
そのリテラル文字列はNULでターミネートされる
配列の長さが+1される

べつにNULターミネートしなくても
文字列は扱える

つまり長さが保存されないかわりに
NULでターミネートされてる
それをcでは文字列と呼称している
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況