をるふちゃんのブログ

C++ | DirectX | VC++

【新入生向け】会津大 新生活の心得(全部入り)

自分について

まずは私が誰か、ということですが、二年連続で単位を落としまくって実質1年生からやり直しとなった3年生です。
辛いことがあって休学みたいなことしてたせいです。そこを掘り下げても仕方ないのでさらっと流してください。
ですから授業で一緒になるかもしれません。その時はよろしくどうぞ。

ともあれ、この2年で一人暮らしを始めたり大学という慣れない空間に身を置いて感じたことをお伝えして新生活に備えていただきたいと思って執筆しています。

それとこの記事はめちゃくちゃ長いです。18000文字以上あります。
気長にどうぞ。

合格おめでとうございます

様々な理由で弊学に来られたことと思います。
第一志望だった方、よくぞ頑張っていらっしゃいました。
失敗してここに来た方、会津も良いところです。決まったものには向かっていくしかありません。腐らず気を取り直していきましょう。
ちなみに私は上位校から逃げてここを受験しました。

幸いなことに弊学は東京や京都で受験ができますので、私のように一度も会津大を見ることなく受験を決意された方もおられるかと思います。
合格発表後まもなく入学手続きがありますので驚かないように。

合格してから入学するまでのこの期間の不安と期待を埋めるものとしてぜひゆっくり当記事をご覧ください。

入学手続きについて

書類

これをお読みになる頃には入学手続きの書類が届くと思います。
くれぐれも忘れることのないように…と言っても一枚忘れたりとかあります。

ことあるごとに「学生課は使えない」などと在校生は口を揃えて言いますが、そんなことないです。確かに融通がきかないこともありますが、とても大らかで親身になって相談してくれる方々が揃っています。
書類不備で家に帰れ!なんてことはないのでご安心を(とは言っても忘れていいわけではありませんが…)。

髪型に気をつけて!

この時学生証に掲載する写真を撮影します(郵送の方は送付する写真ですが)。
ある程度まともな服装と髪型にしてくることをおすすめします。

手続きが済んだら各種勧誘が待ってると思います。

会津は寒いです

早めに行って家を決めること。
早めに来すぎて寒い会津に5時頃到着して凍えてた私もおりますが、ともあれ高速バスなどを利用して来られることと思います。
南方からおいでになる各位は特に気をつけていただきたいのですが、 めちゃくちゃ寒いです
手袋マフラーはあるなら持っていったほうがいいでしょう。耳が冷えやすいのでニット帽があるとなお捗ります。
また雪も残っています。歩行に支障はないと思いますがお気をつけて。
残念ながら私はその頃東京に帰省していますが、だれか先輩に会えたりするかも。

アクセス

駅から大学までは結構な距離があります。
2.5kmなので歩けるといえば普通に歩けますが親御さんは大変かも。
中央病院・居合団地線というバスがあり、大学の前までいけますが時刻表はお察しの通り(お気づきだろうか、ここは田舎だ)。 f:id:wolf_cpp:20170305001320p:plainf:id:wolf_cpp:20170305001325p:plain

手続きは弊学の食堂で行います。
正門からまっすぐ行くと図書館の先にある円柱状の空間のすぐ先です。
入ったところは二階で、そこから螺旋階段を下ったところにあります。迷うことはないと思いますが参考まで。

入学手続き後のあれこれ注意点

食堂定期

食堂定期はぜひ購入をおすすめします。自炊しようと思っていても新生活最初はいろいろ大変なので朝の心配いらないというのはでかいです。それと早めに来る習慣をつけておくのはとても良いこと。

電子辞書

電子辞書は…買わなくて結構。受験生だった皆さんならいまお持ちのものがあるでしょうし、高校と違って大学は基本的に授業中に携帯を操作しても気にされることすらありません(例外はありますが空気を読んでどうぞ)。Google翻訳や検索をうまく活用したほうが圧倒的に効率がいいです。

個人用パソコンの必要性

パソコンは 授業についていく目的であれば 必ずしも買うことはありません。演習がある授業では計算機室(パソコン室のようなものですが情報系大学では「パーソナル」なコンピュータではないのでこう呼んだりします)で行うのでこだわりの開発環境がない限りはそちらを利用すれば十分でしょう。そういう方はもう既にパソコンお持ちでしょうし。

親に買ってもらえなくなる?…かもしれませんね。もう少し補足します。
もちろん持っているに越したことはないのです。授業中にコンピュータで色々できるというだけで捗るもので、というより自分でも家や食堂やときには講義室でいじりたくなることも多々あるでしょうし、真面目に開発に取り組もうと思うなら最終的には自分で買うことになりますので。
と言うか本音は、まじで買って と言いたい。高い買い物ではありますが何のために大学に来たのか考えれば買わない理由のほうがない。これは後で話します。

パソコンの選び方

さて、買うなら英字キーボードのものをおすすめします(弊学の計算機はすべて非日本語配列)。USキーが選択できるノートパソコンはLENOVOThinkpadDellXPS・AlienwareかMacくらいなので選択肢は少ないですが大学と同じ配列で使えるのは大きいです。
ちなみに私はDellのXPS13を使っています。intel i5 6200U / 8GB RAM / 256GB NVMe SSD / Full HD といったところ。これだけあれば一般的な開発用途にも十分に耐えうるでしょう。ちなみに14万5千円でした。使用感などは質問ください。お答えします。

  • i5より低いCPUだと他のパーツの性能が低いことが多いです。
  • メモリが4GBだとあらゆるソフトウェアの動作も開発用途では厳しいでしょう。
  • SSDでなくHDDは遅いのでイライラします。また256GBでも開発環境だけで結構お腹いっぱいになります。
    ちなみにNVMeは極めて高速ですがこれは必須ではありません(SATA3 SSDでも十分早い)
  • Full HD(1920x1080画素)ディスプレイがあると作業が圧倒的に捗ります。
    これより低いものはハーフHDと呼ばれる1366x768になりますが、正直ブラウジングが精一杯です。中古ならともかく開発用途なら狭すぎておすすめしません。

Thinkpadだと部品交換が簡単で(単体で売っていたりもする)、中古も多いので予算下げたい方に特におすすめ。
後述しますが、Windowsの他に大学の環境と合わせて何らかのUNIX OSも追加で導入すると捗るかもしれません。

自作パソコン(?)

またデスクトップパソコンを買う…と言うか作るという選択肢もあります。 自分でパーツを選んでパソコンを完成させるやり方です。
10万も出せば満足に動くものを組んでお釣りが来ますし、20万も出せばゲームもヌルヌル動くマシンが出来上がるでしょう。
自作パソコンならいくらでもこだわれますし、そこには一家言あるので聞いてみてください、見積もりますよ。
ただ持ち歩きできなくなるのが難点ではあります。

体育着

体育着なども指定はありません。靴は体育館で使えそうなものを一足下ろせばいいと思います。高校のジャージ一式で十二分に対応できるでしょう。

教科書セット

教科書セットは基本的にはまるっと購入することになります。私見を述べるなら「明解C」は必要ない(授業で使わない/他の技術書のほうが質が高い)ですが、C言語に触ったことがないならばとりあえず買っておいても損はないでしょう。
また「ハンドアウト」なるものを購入させる文化があります。 教授が作ったスライドをただ印刷しただけの冊子でやたらとぼったくり価格ですが、 これは買わないと厳しいです。まぁ買わないで少々エスパーを用いれば対応できちゃったりするのですが 買え買えとうるさいし単位出さないぞと脅してくる(場合がある)ので。

新居探し

手続きの日には食堂奥には不動産屋さんが控えています。家は早めに決めることを強くおすすめします。いい物件からなくなっていくので。

物件の選び方

家を決めるにあたって抑えておきたいところは以下のとおりです。

  • 大学から近いか
  • コンビニ・スーパーは近いか
  • 部屋の広さ
  • 台所の広さ・キッチン環境の広さ(特にガス台)

ガス台に関しては妥協の産物です。私の家はたまたま2口コンロを置くスペースがありましたが殆どの物件は1口のビルトインとなります。
自炊をするにはかなり厳しい環境なので自ずと外食が増え出費もかさみます。

部屋は案外狭くなる

物をおいていくとかなり手狭になってくるので内覧で広いと思っても案外馬鹿になりません。
大型家具は以下を考慮すると良いと思います。

  • 机と椅子
    椅子を引いて立ち上がることを考えるとかなりスペースを取ります。
    机は奥行き60cm、椅子で80cm以上あると余裕があります。
    ニトリで最大140cm幅の足と天板が別売のテーブルがありましたがお得なのでちょっとおすすめ。
  • 本棚
    増えていくと延べ横幅で180cm(私の家です)とか行きますが、縦長のものを買うとかなり節約できます。
    先を見越していくなら値は張りますが背が高いものを。
  • 布団
    でかいです。めちゃくちゃでかい。90x180が標準です。ベッドは畳めないのでよく考えて購入すること。
    布団をフローリングに直接敷くと寒いので断熱材を検討するといいかもしれません。
    布団をたたんだときのスペースも考慮しましょう(押し入れがあると優秀)。
  • ちゃぶ台・テーブルなど
    飯を食うところですな。
    こたつにすると冬は吸い込まれるのでお好みで。これまたスペース取ります。
    70x70程度ですが座布団を置くことを考えると…。
  • コート掛け
    よく見かけるタイプが80x50程度。配置に困るので地味に邪魔なユニットです。
  • 洋服たんす
    40x60といったところでしょうか。本棚の並びに配置することになりそう。

これに加えて棚を1つ2つ…と考えると6畳も手狭なものです。

物件内覧でチェックしておきたいこと

メジャー持参

計画立てやすいので内覧のときメジャーを持っていくとよいです。
メモれば比較になりますし、物件が決まってから入居までに家具などのアタリをつけやすいので。

地図とにらめっこ

学食で物件に当たりをつけたあと車で内覧することになります。
車の移動速度と自転車・徒歩のそれは全く感覚が異なるのでよく地図と周囲の景色を見ておきましょう。
坂が多い移動だとあとあと辛いです。

新生活

無事手続きや物件が決まったとしましょう。
いよいよ入居の日です。

家具

家具を揃えなければいけません。

押さえておきたいお店

  • ハードオフ
    中古品ですがかなりモノは揃っています。手前側の玩具売場で足を止めると財布が死にます。
  • ニトリ
    やや高めですが質は良いでしょう。
  • ダイユーエイト
    ホームセンターです。一通り物が揃っている上、生活雑貨が揃えやすいのが魅力です。
  • ヤマダ電機
    家電はここが買いやすいかもしれません。他の店で揃えられるなら必ずしも行くことはありません。
  • ダイソー
    言わずと知れた100円ショップ。小物はここで一気に揃います。

なんだかんだとものが増えていくので親の車が使えると便利だと思います。

炊飯器引き取りて募集

また、余談ですが私の中古で良ければ炊飯器を先着1名に差し上げようと思います。Twitterに連絡ください。(無料ってことです)
加えて、家具組み立ての手が必要なら呼んでもらえれば手伝います。先輩呼びつけるなんて怖いって?ご安心を、奉仕活動したい人なので。

揃えるものリスト

地味にかなりの量を揃える必要があります。参考にしてください。

  • 炊飯器
  • 電子レンジ
    (レンチンしない人なら必ずしも不要)
  • 冷蔵庫
    (自炊派は小さいものを買うと後悔する)
  • 洗濯機
    (コインランドリーは面倒だし高価)
  • まな板、包丁
  • 皿、コップ
  • 箸、フォーク、スプーンなど
  • キッチンバサミ
  • お玉、フライ返し、あくとり(以下略)
  • 鍋(片手鍋と深めの両手)
    フライパン(大小あると便利)
    蓋(別売りが多い、サイズをよく見て)
  • キッチンペーパー
  • 食器水切りカゴ
  • キッチンたわし、スポンジ
  • 食器洗剤、クレンザー(重曹もあるともっと捗る)
  • 風呂洗剤、風呂たわし
  • 風呂用ボディタオル、バスタオル、バスマット、シャンプーなど一式
  • 歯ブラシ、歯磨き粉、コップ(抗菌プラスチックだと洗面台で使い勝手が良い)
  • トイレ用洗剤、トイレブラシ、トイレ拭き取りシート(便座掃除)、トイレットペーパー
  • 漂白剤
    (ハイター/キッチンブリーチは万能)
  • 洗濯洗剤
    (蛍光増白剤なしがおすすめ)
  • 本棚
    (背が高い物を買っておくとあとあと買い換えなくて済む)
  • コート掛け
    (強度と価格は正比例)
  • 洋服たんす
  • 洗濯物干し
    (冬季は凍結のため基本的に室内干しになります。突っ張り棒でも良し)
  • 洗濯物用かご
  • パソコン
    (やっぱり買っておくといいよ)
  • プリンター
    (大学でも印刷はできますが…そのために計算機室に行く手間よ)
  • ガムテープ、荷造りひも
    (引っ越し初期はやたらと使う)
  • 石油ストーブ
    (エアコンでも大丈夫ですが、冬季の冷え込みはとても厳しいのであとで買い足してもいい/オフシーズンの今買うと安い)
  • 石油缶
  • 布団一式
    (新調するなら保温性重視で)
  • カーテン
    (レールの幅をよく見て。2枚入りと1枚入りとあったりします/厚手と薄手二枚あるといい)
  • 箒とちりとり
    (汚れます、まじで)
  • バルサ
    (物件によってはダニがいらっしゃったりします/家具などの買い出しの前にプッスーしておくといい感じ)
  • ゴミ袋
    (地味に買い忘れて部屋がゴミで溢れかえったりする)

こんなものかな。抜けがあったら申し訳ない。

自転車は必須

自転車はまじで買わないと詰みます。
ダイユーエイトなどで叩き売りしているので適当なものを買われるといいと思います。
変速機は外装のものをおすすめしますが、正直いってどれ買っても大差ない。
タイヤが太いと冬季の雪も多少なら対応できたりするので参考まで。(ちなみに私はオールシーズン自転車で乗り切りました)

インターネット

インターネットはできるだけ早く工事予約を入れることを強くおすすめします。
物件が内定した段階で予約を入れに行くこと。
どのみち工事は最速で3週間後とかなので、家に光が入るまでネットなしというのもまたきついものです。

プロバイダは大手ならいいと思いますがたまに地雷もあるような噂も聞きます(要出典)。

光熱水

水道、ガス、電気は入居日とかに不動産屋経由で契約・開通に来てくれるっぽいので適当にサインをたくさん書いたりします。

新入生オリエンテーション

なんてことはありません。よくある説明の連続です。 退屈です。
またこのあたりからTwitterが荒れてホモが増殖し始めますがその雰囲気に飲まれないように。 マジで時間の無駄です。
合宿では人狼とか盛り上がるかもですが、日中座りっぱなしで体も痛いしすぐ眠くなることでしょう。

あの時期の大講義室はまじで人がゴミのようにいらっしゃるので早めに席を取っておかないとギリギリ席が足りなかったりします。
このタイミングでパソコンおっぴろげてなんかやってると確実にTAに目をつけられます(いい意味でも悪い意味でも)。

講義

どうでもいいですが大学のMacから自宅のWindowsにリモートで繋げて作業してたりするとTAが目を剥いたりします。やっぱり目をつけられます。特に何もありませんが。
このあたりで情報系に造詣が深い皆さんは退屈してくるので適宜Twitterなどでガス抜きし始めます。

数学の講義はぶっ飛ばすのでまじで寝ないように。初期で授業一回でも落としたらもう何言ってるかわからなくなったりします。
代返とか…いや余計なこと言わない方がいいな

休み時間

移動時間となる休み時間は10分です。
研究棟と講義棟の距離は結構あるので迅速に。特に入ったばかりだと部屋がどれかわからないことが多々あるのでオリエンテーションの合間を使って下見しておくといいかもしれません(特に研究棟→英語の講義室)。

タイムスケジュール

時限 開始~終了
1 9:00 ~ 10:30
2 10:40 ~ 12:10
- 12:10 ~ 13:10
3 13:10 ~ 14:40
4 14:50 ~ 16:20
5 16:30 ~ 18:00
6 18:10 ~ 19:40

少なくとも新入生に6限はありません。主に再履修と「課外プロジェクト」の時間となっています。

課外プロジェクト

1年生から研究室の門戸を開くものです。
研究室の 怖い 先輩方や教授が様々な分野について教えてくれる内容らしいです(私は受けたことがない)。
オリエンテーションの冊子に開講一覧があるので眺めてみてください。

大学とはどんなところか

大学教授は高校までの教諭と違って、 研究者として来ています 。もちろん教えるという側面もありますが、それはある意味共に研究をするであろう一種の後輩として育ててくれているわけで(我々はそのために授業料を払って大学に行く)。ですから自分から能動的に勉強していかないと何をしたらいいのかわからなくなったりします。

サークル活動もあるって?もちろんそうです。ただそのために大学に行くわけではないでしょう。また学位のため(就職のため)と割り切っている人も多くいると思います。しかしなんとなく研究室に入ってなんとなく就職するには総額300万を払う理由としてはあまりにもったいない。

受験という関門をくぐり抜けて、せっかく最先端の研究を行っている教授に学びを乞う環境を得たのならそれを最大限活用して自分の学びに変えていくという姿勢を持ってもらいたいものだなと私は思います。
いえ、何を求めて大学に来ても構わないですよもちろん。ただ良い環境に来れたんだなという意識はどこかに持っていると今後の伸びが違います。

授業の枠を飛び出そう

一つの道を示すならば、自分でも家や食堂や図書館でプログラミングをしてみることです。

とはいえプログラミングと言ってもよくわからない人のほうが多くいることでしょう。
授業で習うC言語、これはCの幾つかの規格の中でもかなり古い「ANSI C」をベースに1年間かけて学ぶことになります。この遅さがやる気を失う原因だと個人的には思っているのですが、つまりどんどん先へ進んでいこうという提案です。
ざっくり言って数ヶ月でマスターできるはずです。
ですからその先にある言語「C++」や、あるいは他の言語・手法・技術を自分で勉強して先へ先へと進んでいくべきです。

高校と違って、授業を待ち構えて宿題に明け暮れる時代はもう終わりました。
講義で学ぶことを活用して今後社会に出たり、あるいは研究者として活躍するための学びを得る場所と心得てください。

私が取り組んでいること

会津大に来たということはプログラミングなどの情報科学に多少なりとも興味があってここを選んだことと思います。
自分が取り組んでいることについてお話しましょう。

私はゲームを書いています。そのツールはC++言語を中心に、DirectXというグラフィクスライブラリ…すなわち画面に2D/3Dの物体を表示したり変形する計算を行うライブラリ…を使って日々開発をしています。
そのために必要な知識も多岐にわたります。

などをやっています。

また、その関連で書籍も鬼のように増えていきます。

f:id:wolf_cpp:20170304160740j:plainf:id:wolf_cpp:20170306062217j:plain

技術書だけで20万くらいはかけたんじゃないかな。
読みたくなってきましたか?いい傾向です。というかどうぞ読みに来てください。大歓迎です。

ゲームをただ作るだけならこれらの知識は必ずしも必要ありませんが、ゲーム開発者として将来やっていくために気合を入れて取り組んでいます。
というのも専門学校に行けば最低限DirectXC++を使ってゲーム開発ができるようになりますが、例えば高度な解析力学などについて言及しているわけではないでしょう(要出典)。大学にいるというアドバンテージを最大限活用していきましょう。

圧倒されましたか?

これらの分野じたいは4年までの大学のカリキュラムに上がっているものがほとんどです。

ですから真面目に授業に取り組んでいけば下積みとなりますし、独学と併せて勉強していけば苦労はしますがもっと早く身につけることができます。

ただ強調しておきたいのは大学は研究者としての機関なので、何か作品を作る場所ではありません。例えばゲームを作るための具体的なライブラリについては一切言及されないのでそのあたりは自分でやっていく必要があります。

なぜ大学を出ると就職が安定するのか

どのような学部であれ、各分野をそこまで深く掘り下げた講義を身につけたということを卒業単位という形で証明し、それだけ突っ込んだ研究をして学位論文として認められた、という一種の資格のようなものを得ることになるからです。

大学を卒業した、それが少なくともある程度「使える人材で根気もあるであろう」という根拠として使いやすいから、だから専門卒と違って「即戦力にはならないけど頭はいいはずだから採用して育てよう」ということで新卒採用というものがあるのです。

しかしさぼっていても皆卒業していくじゃないか、その通り。それは単に高校までと同じようになんだかんだサボっていても最後の最後に帳尻を合わせて卒業できてしまうからで、採用担当者もそれはわかっています。

だから書類審査や面接があるのではないでしょうか。

確かに単位と卒論さえあれば卒業はできる。しかしそういう態度は百戦錬磨の社会人と話せば 必ずバレます 。だからよく言われるように内定が取れないのではないか、と私は考えています(まだ経験したわけではないので憶測ですが)。

もうおわかりだとは思いますが、ただ単位を取るためではなくちゃんと内容を押さえて着実に自分の学びとしていくことが大切です。

というかせっかく授業料払うのだから。特に奨学金を取る皆さん、それは大学で学ぶことで増えるであろう生涯年収の一部を今借りているだけですよ。
ちなみに私は二年間を無駄にしましたがそこについては後悔しているので、だからこういう文章を書いているわけで…(闇)。

ともあれ「大学に受かった、これで将来安泰だ、今のうちに目一杯遊んでおこう(パリピ」などという考え方は間違っています。
これから何をするか。どう自分を高めるか。社会にでるまでに4年間ガッツリ取り組める 最後の チャンスかもしれません。頑張っていきましょう。

周囲に期待しすぎないこと

悲しいことを一つ。
このような情報系バリバリの大学に来たのだからみんなパソコン持ち歩いてワイワイとプログラミングについて語り合いながら本を広げて食堂は切磋琢磨し合う場なんだろうな…。と期待しないほうがいいです。いません。

それはなぜか、なんだかんだ皆さん情報系は興味あってもやったことない人のほうが圧倒的に多いからです。

やり方がわからない

わからないからやらない(やれない)

その状況を見たできる人も表には出さず家で一人でプログラムを書き、勉強する

でも大学に数年も浸かっているとだんだんわかってくる。

しかしその頃には研究室の亡者になり新入生の目のつくところでは魂を吐き出してる。

だから結局誰もやってるように見えない。

こういうサイクルがあるからだと個人的には分析しています。

かと言って、周りにプログラミングやろう!って呼びかけても意識高い系扱いされて終わる。(地味にやりたいと思ってる人はそこそこいるかもしれませんが、声がかけにくい、そして一緒になってもどう進めたらいいか結局わからないので頓挫する)。本当にもったいない。そういう学生さんは多分たくさんいます。

だからこうして私は記事を書いています。
道がわからないなら聞いてください。そして一人で歩めるようになるまで示す、その手助けをさせてください。
どうしてそんなことを考えるのか、こんな大学に来ちゃった皆さんのことが好きだからです。
先輩だからとか遠慮はむしろやめてもらいたいくらいで、つまり頼って欲しいのです。まじで。

他にも先輩はたくさんいます。彼らを触媒にしてなんかこう、学ぶ雰囲気が広がっていくともっと楽しいことになるんじゃないかしら。
なんならそういうサークル立ててもいいと思っていますが、ならばまずは人が集まるところから。

サークル

サークルの話になったので少しだけ。弊学にも様々なサークルがあり活発に取り組まれている学生さんが多くいます。
私はサークルには参加していませんのでその視点からということを先にお断りしておきます。

新入生歓迎会

新歓でいろいろ紹介もありますし、会津城でのお花見会が各サークル主催で行われるので参加するのもいいでしょう。会津城の夜桜は見事なものです。

「飲まされる」という話は聞いたことがありません。当たり前のことですが、飲ませる前提の飲み会ではないですし、いわゆるヤリサーというのも寡聞にして聞いたことがありませんので安心して参加していいでしょう。
ただしその後サークルに流れで入る可能性はかなり高いので慎重にどうぞ。

ICPC

弊学にはICPC部というガチ系プログラミングサークルが存在します。ICPCとは大学間対抗プログラミングコンテストのようなもので、世界大会まであるメジャーな大会です。

プログラミングコンテストとは

与えられた問題を解く(つまりテストケースとして適切な入力をすると正しい解を出力するような)プログラムを書き、完成までの速さとプログラム自体の速度を競うものです。

このような問題が何問か与えられるので、規定の時間(数時間)内に何問解けるか、あるいはより高速に動作するプログラムを提出できるか、あるいはより早く提出できるかを競うものとなっています。

弊学の競技プログラミング

会津大は世界大会まで進出しており、アルゴリズム…すなわちプログラムの手順を覚え自在に使い、それをいち早くプログラムとして作り上げる(実装力)を磨くにはいいサークルだと思います。
かくいう私も高校時代はこのような「競技プログラミング」に取り組んでいました。

競技プログラミングのすすめ?

これの短所としては成果がはっきり出るかわりに制作物としてのプログラムを書けないことが挙げられます。実装の速度を極限まで追求するため、多少の雑な設計は許容し大規模なプログラムを構築する力を問わない傾向があります。ともあれ気になる方は色々やってみると良いと思います。

ちなみに弊学がやっている「Aizu Online Judge(AOJ)」と言うものもあります。これは競技プログラミングの過去問やオリジナル問題をたくさん収録したオンラインの採点システムです。この他にもAtCoderなどといった競プロサービスがありますのでそちらで体験してみるのも良いでしょう。

これも浸かる人はどっぷり浸かっていく印象がありますね。(なお、語彙力が低下していく場合が多い)

バイト

バイトしないと生活できない方もいらっしゃると思いますし、お小遣いがほしい方も多くいらっしゃるでしょう。

定番どころ

私のバイト先であるセブンイレブンなどのコンビニや、ガスト、スーパー、100均、飲み屋、塾、パチンコ屋などが定番のようです。

個人的にはうちの7-11亀賀川西店に来てくれないかなぁ…。とか。

時給

福島県の最低時給は726円で、コンビニなどはおよそそれに準じた額となっています。
深夜給は 25% 増しや 200~300円 加給が多いようです。

パチ屋は 1000円 も超えるようですが音やタバコなどがきついようです。

塾は 1500円 近く行くようですが、時間外労働が多いという噂をたまに聞きます。
それとスーツが必須になるので初期投資が少しかかるかもしれません。

バイトの闇についてはここに書けないので直接聞きに来てください、いくらでも喋ります。

弊学でよく耳にする「ベンチャー」とは

悪く言う意図はないと先にお断りしておきます。

弊学には「ベンチャー」と呼ばれる勢力が存在します。
ベンチャーというとかっこいいですが、本来「(大企業なら手を出したがらないような)冒険的・野心的な事業。起業。ベンチャービジネス。」という意味らしいので当てはまるのかどうかという議論…はさておき、

会津には2つのIT企業が存在します。片方には少し関わったことがあるのですが、どちらも最初数カ月は給料が支払われない/または極めて少ない額となっているようです。
その後徐々に収入は上がるようですが支払い面でのトラブルはいくつか耳にしています。また勤務時間がものすごく長い方も散見されるのでそのあたりを踏まえた上で募集に応じたほうがいいと思います。最初は寿司などのおごりがあるようで釣られる方も多くいるようですが。

ただこれはあくまで働いていない側の意見ですので、違うこと言ってるかもしれません し、中の人に聞くとまた違う情報が得られるかも。

プログラミングを学ぶ場としてのアルバイト

ベンチャー」で「プログラミングが学べる!」という話を聞きますが、自分で勉強したほうが効率がいい(と少なくとも私は思う)。その上で業務というノウハウを覚えるのなら就職したあとでも十分だと思っています。
もちろんプログラミングでお金がもらえるのはいいことですが、別にフリーで稼ぐ方法はいくらでもありますし、バイトはバイトで割り切って開発は自分のやりたいことをやるのもいいと思います(会社だとやりたい勉強が必ずしもできるとは限らない、というかできない)。

さっきの話につながりますが、情報系初心者が何をやったらいいかわからない状態で手探りしているときのきっかけの選択肢の一つがこの「ベンチャーバイト」なのだと思います。

学ぶ場は他にもある

C++/DirectXであれば私が教えますし、JavaHaskellあたりならおそらくこの人とかが快く教えてくれると思います。

課外プロジェクトで学んでもいいですし、独学も乗ってくると効率は最高によい。

その上で「場」を求めるのであれば「強いひと」に教えを乞うのが一番。そしてそのためのお手伝いなら時間が許す限り私もします。
というかゲーム制作に興味ある後輩さん、ウチに遊びにこないかな…とか。

f:id:wolf_cpp:20170304160821j:plain

私見です

もう完全に愚痴ですが、そうやって新入生の段階で素質ありそうな後輩たちがことごとくサークルやバイトに明け暮れているのを見るともったいないなぁ、私が数ヶ月教えれば立派にゲーム開発者の仲間入りもできるのになぁ…と思うことが去年もいくつもあり、そういうところでもっと食いついてくれればいいのにと切に思うのです。
いや、いいんですけどね、自分のやりたいことをやるのが一番ですが。

生活の知恵

洗濯機外置き

まじで死にます。冬季に洗濯機ごと凍りついていたときは絶望しました。
溶かせば良いのですが。あと回収忘れて洗濯物が脱水した形のまま凍っていたこともあります。

ただホースを蛇口から外して洗濯機側の接続緩めたあと洗濯開始を押してカラ通水しておくと水が全部抜けるので凍結はほぼ防げます。
手間が増えるのと外に出るのが寒いのはご愛嬌。私は慣れたものですが。

灯油

灯油の加熱力はマジぱねーですが、ヒーターには二種類あります。

どちらが良いかは賛否両論あるので部屋の構造などと相談。
反射式は新品で 6000円~ ファンヒーターは 10000円~ が相場です。

ハードオフで夏過ぎまでは中古が並んでいるのでそこまでに買っておくと安く手に入るでしょう。

反射式

上にヤカン乗っけたりするやつです。
鏡で部屋中を放射熱で温めます。
換気で空気を温めても壁が温まっているので保温が結構強力です。

ファンヒーター

燃焼筒で燃やした暖気をファンで吐き出すタイプです。
じわじわあたたまる反射式と違って即効で手があたたまる、帰宅直後の神です。
調子に乗ってガンガン燃やしてると石油があっさり切れたりします。そのへんは反射式も同じですが。

灯油の購入

灯油は冬が来る前に早めに買い込んでおくと日々のやる気が違います。

灯油缶はホームセンターで 10L 18L 20L 辺のサイズが売っています。
赤いポリタンクがそうです。

10Lは一瞬で切れるので標準サイズの18Lを勧めておきます…がまじ重いです。計画的に。
私は2缶買って、1缶ずつ回しています。

石油の値段に上下しますが、夏の安いときで 700円~ 冬だと 1100円 くらいまで上がります。
ホームセンターやガソリンスタンドで入れてくれます。

ちなみに行きつけのダイユーエイトではレジで「灯油 nリットルください」というとレシートに印字されるので、それを持っていくと詰めてくれる方式です。

ポンプも忘れずに買うように。
実はあまり知られていないのですが、灯油ポンプはサイホンの原理を使えば楽に移せます。

f:id:wolf_cpp:20170305035137j:plain

このように高低差をつけてからポンプを数回動かすと勝手に流れ始めます。
放っておくと無限に流れ出るので程よいところでポンプのてっぺんの白いネジを緩めると止まります。

ポンプを軽く動かして流し切れば辛い思いせずに灯油が移せます。

これを知るまで毎回筋肉痛でしたね…。


追記: 先輩からの情報です。

弊学の施設

電源確保・パソコンの使用

弊学図書館はパソコン持ち込みできるコーナーがあるので活用するといいでしょう。
電源取れるのは図書館と食堂のボックス席のみで、講義室では基本的にAC100V電源は使えないと思ってください(情報系なのにな)。

また弊学はいたるところにWi-fiが飛んでいます。EAP-TLS認証の暗号がかかっているので安心して使えると思います。

計算機室について

結論から言うとWindows機はありません。
MacSolarisという 変な OSの二択です。

MacApple社が作っているコンピュータで、iMacという機種がそれはそれはたくさんおいてあります。
ちなみにi5 / full HD / 1TB HDDというなんともいえないスペックなので期待しないように。

もう一方のSolarisSun Microsystemsが出しているUNIX系の商用OSです。
最低限もいいところなスペックしかなく、動作ははっきりいって劣悪です。
加えて通常左下にあるCtrlキーとCapsLockキーが入れ替わって配置されているUNIXキーボードで、Mac教室にあるUSキーボードとも違う気持ち悪い配列になっていて、Backspaceと間違えてグレイヴ・アクセント(`)を連打すること間違い無し。発狂しそうですよね、というかしました。
キーボード持ち込んだりとか涙ぐましいことやってましたが、最終的にキー配列弄って表記とは違うけどブラインドタッチできるようにしちゃいました。 私は悪くない。

そんなわけでWindowsゲーム開発者としては私は不満しかなく、そういう意味でもノートパソコンは必須だと個人的には感じました。
UNIXマンやMacマンには関係ないんでしょうね、あ~あ。

追記:そういえばハードウェア実験室の端末がWindowsになるという噂が。

図書館

2階建てで結構広いです。
技術書もそこそこありますが情報は古いです。
日中ぽかぽかして 昼寝 勉強が捗ります。


追記: 先輩からの情報です。

購買

食堂横にあります。
新しい技術書や雑誌がありなかなか品揃えも優秀。
お菓子や軽食や文房具やちょっとしたPC周辺機器など一通り揃っていてコンビニ的に使えます。

学食

大学生活のおとも。
肉料理は特に美味しいです。個人的にはたまに出るミルフィーユカツがおすすめです。
トレイを取って先にものをもらう。最後に精算してから水や食器を取るスタイルとなっています。

ご飯だけタッパーに入れて持ってきて唐揚げ単品購入するとコスパ最強。

講義室

だだっ広い部屋に机と椅子がたくさん。
椅子の座りにくさは半端じゃないので背中が痛くなります。あと狭い。

電源も取れないのでちょっと辛くなります。
なにげに外の景色がきれい

体育館

木造のきれいな建物となっています。
屋内温水プールも併設されていて、体育の環境はとても良いです。

オタクだと引きこもっちゃいますからね

また、SRLUと呼ばれるジムがあります。
筋肉な人はぜひどうぞ。

私は入居してないので詳しくは存じ上げませんが、共同調理場など+個室というよくある構成のようです。
ものも多い学生だったからかわかりませんが、かなり室内は手狭な印象がありました。

調理場は広かったですが、 個人の私物と放置された調理器具がうず高く

寮はユニットごとに分かれているのでそれぞれまた違うのかも。

観光・施設など

会津

会津は歴史のある街です。
花見で行くことにはなりますが、戊辰戦争で半壊した会津城も今はきれいに再建されて、中は博物館のようになっています。
城の周りも綺麗ですのでぜひ一度見に行くと良いでしょう。

飯盛山

少し東の方に行くと飯盛山があります。ご存知のように、白虎隊が自刃された山で、神社などもいくつか立っています。
麓の茶店で食べるところてんは美味しいですよ。

温泉

南に行くと芦ノ牧温泉、西にちょっと行くと東山温泉があります。
また駅から至近距離に富士の湯という温泉があります。
ここは私もよく行くのですが400円で露天風呂や一人づつ入る風呂やウェットサウナ・ドライサウナにいくらでも入ることができます。
ぜひ一度行ってみて下さい。

猪苗代湖

BBQや釣りの良いスポットです。
車があるといいですね…。

お酒

未成年の閲覧者が多いであろう記事ですがあえて書いておきます。

会津の日本酒は美味しいです。
成年したらぜひ親におみやげで買っていっていっしょに飲むと盛り上がるかもしれません。

個人的なおすすめは「栄川」ですが、「名倉山」や「会津中将」、「ほまれ」など本当にたくさんの酒蔵があります。
駅近く、ダイユーエイトの向かいに会津酒楽館という酒屋さんがあったりします。

もちろん、お酒は成人してからですよ!

さいごに

こんな記事を書いているくらいには新入生の皆さんの幸せを願っています。
Twitterにはホモホモしい先輩やウェイっぽい何か、また「新入生です」とアカウント名に嘘を書いている先輩もたくさんいて何を信じたらいいのかもわからなくなったりします。

そういうときに私に聞いてくれるという選択肢を検討してくれるととてもありがたいです。
質問もいくらでも付き合います。

そしてほんとにどうでもいいですが私の趣味は料理で、作ったものを食べてもらうことが大好きです。
C++をはじめプログラミングについて語り合う仲間がもっと増えたらいいなとも思っています。

ですからうちにぜひ遊びに来てください。

そしてともに切磋琢磨し合う友人としてぜひ皆さんが活躍されることを心より祈っています。

せっかく会津大に来たのですから目一杯技術をみがいて、そして生活を楽しんでください。
出来る限りお手伝いします。応援しています!
読んでくれてありがとうございました。

もう一度だけTwitterアカウントを貼っておきますね。

をるふちゃん Twitter
SkypeID : wolf_k_k
この記事にコメントつけてもらっても構いません。

それと私が先日立ち上げたプログラミングのコミュニティがあります。
怖い先輩がたくさんいるのでぜひ覗いてみてください。 コミュニティのWikiはこちら

今、この記事の続編となる自炊入門をぼちぼち書いています。
プログラミング入門なども書いていくのでたまにチェックしていただけると幸いです。

CからのC++入門 【クラスを知る】

クラスを使うメリット

構造体をC言語で学習したと思いますが、それを操作する関数を考えてみましょう。

void setStructData( struct Hoge* hoge);

のように構造体のポインタを受け取って、間接参照でその構造体を操作することができます。

しかしよく考えれば、特定の構造体を操作する関数は他の構造体には必要ないわけで、そういうヘルパ関数はひとまとめにしておきたいところです。
また、そのような関数に限って名前が被りやすいという難点もあります。

そのため、「構造体に関数を紐付けられたら便利ではないか?」とは思いませんか。
そこでクラスです。

とりあえず触ってみる

以下のようなC言語の構造体を考えます。

typedef struct Coordinate_ {
  double x;
  double y;
} Coordinate;

xとy座標を保持する簡単な構造体ですが、原点からの距離を求める関数は以下のように書けます。

#include <math.h>

double Distance( struct Coordinate ){
  double t = Coordinate.x * Coordinate.x + Coordinate.y * Coordinate.y;
  return sqrt( t );
}

しかしこの関数はCoordinate構造体以外には関係ありません。
必要ない関数を提供するのはプログラム設計上望ましくありませんし、そもそもその関数名がかぶりそうでよろしくありません。

C++に移植

#include <cmath>

struct Coordinate {
  double x;
  double y;
  
  double Distance();
};

double Coordinate::Distance(){
  double t = this->x * this->x + this->y * this->y;
  return std::sqrt( t );
}

構造体のメンバに関数の前方宣言が追加されていることがわかると思います。
また、このように構造体に紐付けられた関数の記述をする場合、関数名の前にCoordinate::と追加する必要があります。

またtypedefが削除されています。
Cではtypedefしない場合struct Hoge hoge;と書かないといけないのですが、C++ではtypedefしなくてもクラス名を直接Hoge hoge;のように使えます。

メンバ関数の中でメンバ変数にアクセスするのにthis->xとしていますが、これは冗長な表現で、単にxと書くことができます。
ただしメンバ関数の中で同じ名前のローカル変数や引数を使う場合、識別のためにthisを付ける必要があるのであえてこのように記述することもできます。今後のサンプルでは名前はかぶらないようにした上で省略して記述します。

またC言語で使われるhogehoge.hというヘッダはC++においてchogehogeという名前で定義されています。
この場合#inlcude <math.h>#include <cmath>です。


補足: 名前空間

C++では標準ライブラリにはstd::と付ける必要があることにお気づきだと思いますが、これは名前空間という機能です。この名前空間の内側で定義されたクラスや関数には名前空間名::を付加する必要があります。

namespace HogeNS{
//ここに記述したクラスや関数にはHogeNS::とつける必要がある
}

C++の標準ライブラリはすべてstd名前空間の中に記述されている、ということです。

面倒だと思いますか?
確かにそうかもしれません。ですがこの名前空間を階層化することでクラス名の被りを防ぐことができますので今後扱っていきます。


さて、この構造体を使う場合以下のようにします。

#include <iostream>

int main(){
  Coordinate p;//点P
  p.x = 3.f;
  p.y = 4.f;
  std::cout << p.Distance() << std::endl;
  
  return 0;
}

std::cout << p.Distance() << std::endl;C言語printf("%f\n", p.Distance());と同義です。使い方は…わかるかと。iostreamをincludeする必要があります。
ともかくp.Distance()と構造体のメンバ変数と同じように関数を呼べるようになっていることがわかります。
サンプルコードはこちらです。

アクセス指定子

C++の構造体にはアクセスを制限する機能が追加されました。
使い方を見てみましょう。

#include <cmath>

struct Coordinate {
  void set( double x, double y );
  double GetX(){ return x; }
  double GetY(){ return y; }
  double Distance();
private:
  double x;
  double y;
};

void Coordinate::Set( double tX, double tY ){
  x = tX;
  y = tY;
}

double Coordinate::Distance(){
  double t = x * x + y * y;
  return std::sqrt( t );
}

xy座標を格納するメンバ変数への直接のアクセスを防ぐためにprivate:というアクセス指定をしています。
このアクセス指定をするとクラスの関数内部でしかアクセスできなくなります。

例えばこの構造体の実体(インスタンス)があるmain関数などではxy座標に直接アクセスすることができなくなります。このサンプルでは問題ありませんが、この座標が第一象限に限定される実装を行うことになった場合、set/get関数を通じてメンバ変数を操作するならば値チェックが可能です。
しかしメンバ変数のアクセス指定がpublic:である場合、不正な値に書き換えられてしまう可能性が残ります。安全なプログラミングのためにできるだけ活用するするようにしてください。

GetX()GetY()関数ですが、このコードのようにクラスの宣言の中に直接書くことができます。
この場合、関数はinlineに展開されるはずです(されないこともあります)。
もっとも、コンパイラの最適化が働くので分けて書いてもInline展開される場合も多々あるので、単にコーディングの好みの問題になります。個人的にはワンラインで書ける程度のGetter/Setterはヘッダに直接書くことが多いです。

サンプルコードはこちらです。

ところでクラスとは

いままで全くクラスの話が出てこない?
実はCの構造体とC++とのクラスとの差はたったひとつだけです。

クラスではデフォルトのアクセス指定はprivate:であることに対し、
構造体ではpublic:となっています。
これによりCのコードを問題なくコンパイルしつつ安全にコーディングできるようになっています。

今回はここまで

次回はコンストラクタ・デストラクタを扱います。

ちなみにこの記事はこちらに投稿されたものと同じです。

懲りずにコミュニティ作りました

出来心だったんです

はこだて未来の某とか岩手県立の某Twitterで喋ってて、「LTとか輪行会、学外ともやりたいよね」って話になってとりあえずその辺の大学でわいわいしようぜってことでDiscord立てたところ、芝工や筑波や大阪電通に室蘭に…数時間足らずでいろんな方々が40人以上集まりまして。

まあ既に色々とヤバいんですけど。

会の正体が知りたい方、こちらへどうぞ。

思うこと

まぁこれはWikiっぽいなにかにもそれとなく書いたんですが、 マジで意識高い系の何かにはしたくない
Twitterよりも情報密度高いしわいわいできりゃとりあえずそれでいいんだよなあっていう。
私はどんどん記事書いていくつもりですし。
あとは過疎らないといいね。まあこういうコミュニティあるあるなんで避けがたいものなのかもしれませんが。

いつも絡んでる方々が結構来てくれててるのでそこそこ動かせそうやなって。
みんなも協力よろしくね。

「私が」やりたいこと

人々のレベルに応じてC++DirectXのお話、資料アップロードと解説。
またこの辺のメンツでLTや輪行会、勉強会やハッカソン等のイベント。
それ以上の何かはあんま考えてません。
プロジェクトやろうとすると破綻するのはよくある話ですし。
まぁ考えすぎず好きに使ってくださいな。

とりあえずWiki動かしてタイムラインぶん回すことに注力しましょうぜ。ほんとマジで。

一言申し上げるなら

とりあえずこんなに集まってくれてありがとう。これからもよろしくね。
私も活用していきたいんで引っ張り込みよろしく。フレンズが増えるよ!たーのしー!

DirectXのエラー処理

この記事(デバッグアサーションとかのメモ)の続編ってわけでもないけど。
例によってVC++以下略。

こいつらはすべてリリース版では除去される。

エラー処理

エラーコードを示す文字列を返す

TCHAR* WINAPI DXGetErrorDescription( HRESULT hr );MSDN
そのまんま。HRESULT リターン コードを受け取ってエラーコードを示す文字列を返す。

エラーコードに関連付けられている名前を返す

TCHAR* WINAPI DXGetErrorString( HRESULT hr);MSDN
同様にHRESULT リターン コードを受け取ってエラーの内容を示す文字列を返す。

エラーコードを文字列に変換してデバッガに出力する

HRESULT WINAPI DXTrace(
    CHAR* strFile,  // ファイル名。 __FILE__ マクロを突っ込んでおくといい。
    DWORD dwLine, // 行番号。 __LINE__ マクロを以下略
    HRESULT hr, // エラーコード。内部でDXGetErrorStringを呼んでくれる。
    CHAR* strMsg, // オプションとして表示する文字列へのポインタ。
    BOOL bPopMsgBox, //メッセージボックスを出すかどうか。TRUEで表示。
);

MSDN
説明は不要っぽい。

エラー処理マクロ

DxTraceを扱いやすくしたもの。

エラー情報をデバガに投げる

HRESULT DXTRACE_ERR( char* str, HRESULT hr );MSDN
内部ではこんな感じ。
DXTRACE_ERR(str,hr) DXTrace(__FILE__,(DWORD)__LINE__,hr,str, FALSE)

エラー情報をメッセージボックスに投げる

HRESULT DXTRACE_ERR_MSGBOX( char* str, HRESULT hr );MSDN
内部ではこんな感じ。
DXTRACE_ERR_MSGBOX(str,hr) DXTrace(__FILE__,(DWORD)__LINE__,hr,str,TRUE)

文字列をデバガに投げる

HRESULT DXTRACE_MSG( char* str );MSDN
内部ではこんな感じ。
DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE)

デバッグアサーションとかのメモ

エラー処理などなどちゃんと書いていこうと思った次第。
例によってVC++の話なのでLinuxの人はお帰りください。

メモリリーク検出

以下のコードをwWinMain.cppらへんに突っ込んでおく

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
//...
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow ) {
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
//...

}

もちろんwWinMain()じゃなくてmain()でも動くよ。
最初の3行は順番変えたりすると上手く動かないみたい。

これでVCのデバガでメモリリーク検出してくれる。mallocnewらへんは普通に対応してくれる。

デバグコード

crtdbg.hを使うとデバグ時に_DEBUGマクロ、リリースビルドではNDEBUGマクロが定義される。
あとは

#ifdef _DEBUG
    //デバグ用のコード
#else
    //リリース用のコード
#endif

みたいに使えばいい。簡単。

アサーション

crtdbg.hにある_ASSERT()_ASSERTE()マクロを使う。
使い方はシンプルで、引数が偽なら殺してくれる。

switch-casedefault:_ASSERT(false)とか書いておくとデバグビルドで問答無用で落としてくれる。
_ASSERTEマクロはファイル位置や行も教えてくれるっぽい。

_DEBUGマクロが定義されてなければ(リリースビルドでは)除去してくれる。

例外処理

使ってね。(ここに書くには仕様が重い)

デバッガ出力

OutputDebugString( LPCTSTR lpOutputString )を使う。
デバガに文字列を送信してくれる。

ポインタと仲良くなる話 【初心者C++er Advent Calendar 2016 - 14日目】

ㄘんㄘんついてないから大丈夫。 ん??なんの話??

…じゃなくてすみません。忘れてました。

当記事に前後して こちらの記事 もご覧頂けると理解が深まるかもしれません。

メモリのアドレスとは

C++において、変数はデータを格納し必要に応じてそれを使えるようにするために データに名前をつけたもの です。
この「データ」はコンピュータのメモリ上に置かれるため、各変数はメモリ上の「場所(位置)」である アドレス を持つことになります。

このアドレスは一般的な環境においては8桁の16進数( = 4byte = 32bit )で表されます。

「アドレス」をデータとして格納することのできる型をC++ではポインタと呼びます。
ポインタはその性質上、任意の変数に対して別の方法でアクセスする方法を提供することができます。すなわち、ポインタを介して任意の変数を操作することができます。

ポインタを介して変数を操作する際に必要な情報は以下の2つです。

  • データの格納されているメモリ上の位置( = アドレス )
  • データを何バイト分読めばよいか

後者について補足しましょう。
先ほど紹介した記事に詳しく書かれていますが、とある事情 により、メモリは8bit( = 1byte )ずつ区切られて使われています。
しかし1byteに格納できる情報はたかが知れています(256通り)。このため幾つかのメモリブロックを連続して専有することで多くの情報を扱えるようにしています。

例えば多くの環境ではunsigned intは4byteとされています。つまり4つ分のメモリブロックを使うことで0 ~ 4,294,967,295の範囲でデータを格納することができるようになっています。
このため、メモリアドレスをポインタに格納するにあたって、正確には以下の情報を扱わねばなりません。

  • データの格納されているメモリブロックの 先頭 位置
  • 格納したいポインタの元となる
    ※型がわかれば何バイト読めばいいかわかりますから。

後者については、ポインタを変数の型に一対一対応させる形とすれば解決できます。このため ポインタにも型 があります。
そのため、ポインタの宣言時には型の直後に*を置いて区別しつつわかりやすいものとしています。

ポインタをとりあえず使う

以下のように、型名の直後に*を追加すると任意の型に対するポインタを定義できます。

int* pInt;
char* pChar;

ポインタに代入できるのはメモリのアドレスです。
メモリのアドレスは任意の変数名に&を付けることで取得できますね。

すなわち、

int i;
int* pInt = &i;

char c;
char* pChar = &c;

また、ポインタに格納されたアドレスにあるデータにアクセスするには、ポインタ名に*(間接参照演算子)をつける。

int i = 10;
int* pInt = &i;

std::cout << *i; // 10と出力される

ここでの*(間接参照演算子)と、先ほど定義の際に型名の直後に書いた*は全く別物であるということに注意してください。

ポインタを活用してみる①

任意の変数に対する別名(エイリアス)のようにポインタを使っているのでは意味がありません(むしろわかりにくい)。

ポインタの力が発揮されるのは例えば以下のようなときです。

  • 任意の関数に書込み可能な領域を提供したいとき

コードから見てみましょう。

#include <iostream>

int squa(int i);

int main(){
  std::cout << squa(5) << std::endl;
  return 0;
}

int squa(int i){
  return i * i;
}

このような関数を改良(改悪)し、値を返すのではなく直接書き換えるようにしたいとします。
しかし以下のようにすると上手くいきません。

#include <iostream>

void squa(int i);

int main(){
  int a = 6;
  squa(a);
  std::cout << a << std::endl;
  return 0;
}

void squa(int i){
  i *=  i;
}

動作としてはsqua()に渡したaが書き換えられて36になることを期待していますが、これは当然上手くいきません。
関数の呼び出し時にはコピーコンストラクタが呼び出されるからです(つまり関数呼出し時に複製が行われ、元の変数とは違うアドレスに仮引数として新しいデータが作られる)。

これを解決するためにポインタを利用することができます。

#include <iostream>

void squa(int* i);

int main(){
  int a = 6;
  squa(&a);
  std::cout << a << std::endl;
  return 0;
}

void squa(int* i){
  *i *=  *i; //冗長に書くと、 (*i) = (*i) * (*i);
}

挙動はざっくりと以下の通りです。

  • squa()の仮引数はポインタである
  • squa()が呼び出されるとコピーコンストラクタが呼ばれ渡したint型変数のアドレスが仮引数として定義される。
  • 仮引数のポインタを間接参照して、呼び出した時にアドレスを取得した変数(ここではa)に自身をかけ合わせて2乗の計算を行う
  • ポインタ経由で直接aを操作したので書き換えに成功した

ですから、C言語printf()には不要な、&scanf()で要求されるのはそういった事情があるのです(書き換えを行う必要があるのでメモリアドレスを取得する必要がある)。

だがしかし

このようなやり方はC++ではおすすめできません。
C言語にはない新しい機能「参照」を使ってよりスマートに記述できるからです。

参照型について

参照型は任意の変数に対する別名のようなものを提供します。
これはメモリアドレスを渡す必要はなく、 宣言時に 変数名をコンストラクタで渡すだけです。
ただしポインタのように参照する対象を変更することはできません。
また、参照型をつかって間接的に元の変数を操作する場合にも*(間接参照演算子)は不要です。
参照型につけた名前をそのまま書くことでアクセスができます。

ポインタの宣言時にはint* ptrなどと書きますが、その代わりに以下のように記述することで「参照型」変数を定義することができます。

int i = 10;
int& ref = i; //アドレス取得の& は不要

ref = 15; // i は 15になった。
std::cout << i; //  15が出力

i = 20 // このとき ref にアクセスすれば 20である。
std::cout << ref; // 20が出力

int j = 30;
ref = j; // ref の参照先はjにならず、ここでは i に値30が代入されるだけ。
std::cout << i; //  30が出力

j = 40;
std::cout << i; //  30が出力。jを変更しても参照しているわけではないので影響はない。
std::cout << ref; //  30が出力。上に同じ。

これを変数の仮引数に用いると、ポインタなしでより安全に書き換えを行うことができます。

#include <iostream>

void squa(int& i);

int main(){
  int a = 6;
  squa(a);
  std::cout << a << std::endl;
  return 0;
}

void squa(int& i){
  i *=  i;
}

仮引数として参照型が使われているので、関数がコールされる際に呼ばれるコピーコンストラクタでsqua()のブロック内にaエイリアスが作られるので、関数内での操作は呼び出し元に反映されます。

特に問題がない限りこの書き方を推奨します。このため、このような用途においてポインタはおすすめしません。
だめじゃん。

ポインタを活用してみる②

以下のような時、ポインタは絶大な威力を発揮します。

  • メモリを動的に確保する

ざっくりと説明すると、メモリをヒープで確保する( = メモリ資源を上手く利用する)ためには以下のような方法を取らないといけません。

  • ローカル変数での大きなデータの確保は極力避ける
  • ヒープで取れる方法を利用する

まぁSTLとか使っておけよという話なんですが。

new/delete

newについてもかんたんに触れておきます。

newnew演算子の直後に書いた型に対応するメモリ領域を確保し、その先頭アドレスを返す 演算子です(mallocも似ていますが、sizeofなどを使って確保するサイズをbyte単位で指定する必要があります)。
HogeType* ptr = new HogeType;

また、これはフリーストアと呼ばれるメモリ上の任意の位置を専有することになるので、プログラムを終了する前に 必ずメモリを解放 してください。
delete演算子に解放したい領域の先頭アドレスを渡すことで解放を行うことができます。
delete ptr;

メモリ解放は、 過不足なく 行うようにしてください。
殆どの場合、二重解放を行っても実際に問題が起きることは少ないですが、万が一、一回目の解放後に同じ領域に別のデータが割り当てられた場合、意図しない解放とセグメンテーション違反を起こすことになります。
この種のバグはたいへんデバグが難しい上に再現性がないのでとても追跡が厄介です。

もし心配であれば以下のようにすると良いでしょう。

delete ptr;
ptr = nullptr;

また、newでは配列を確保することもできます。
その場合、以下のようにします。

int* ptr = new ptr[10];
ptr[0] = 3;
ptr[1] = 1;
ptr[2] = 4;
ptr[3] = 1;
//~~中略~~
delete [] ptr;

deleteのあとに[]を置いていることに注意してください。配列を動的に確保した場合はこのように解放します。

動的確保しても配列にアクセスする際はアスタリスクをつけないので混乱するかもしれません。
この話はこの後の「余談」の項で扱います。

ともあれ、このようにするとメモリを動的に確保することができ、フリーストア領域を活用してスタックを消費することなく大容量のデータをメモリ上で上手く扱うことができます。
ゲームのコードを例に出してみます。

// main.cpp
#include "GameManager.h"

int main() {
    GameManager* game = new GameManager;

    //~~中略~~

    delete game;

    return 0;
}
// GameManager.h
#pragma once

class GameMap;

class GameManager {
public:
    GameManager();
    ~GameManager();
private:
    GameMap* m_gameMap;
};
// GameManager.cpp
#include "GameManager.h"
#include "GameMap.h"

GameManager::GameManager() {
    m_gameMap = new GameMap;
    m_gameMap->foo();
}

GameManager::~GameManager() {
    delete m_gameMap;
    m_gameMap = nullptr;
}
// GameMap.h
#pragma once
class GameMap {
public:
    void foo();
};
// GameMap.cpp
#include "GameMap.h"

#include <iostream>

void GameMap::foo() {
    std::cout << "worked!" << std::endl;
}

こんな感じです。
GameManager.hにて、class GameMap;と書いています。
これはクラスの前方宣言という記法で、 クラスの実態を必要としない場合は、そのクラスの存在をコンパイラに知らせるだけでよい というやり方です。
これによりヘッダのインクルードを減らし、あるいは隠蔽することができます(GameManager.cppで初めてインクルードしていますが、実装の詳細でヘッダを初めて読むので一回で済む)。
リンクライブラリ化する時に特に効果が出ますが、より良いC++API設計の観点からもヘッダから依存関係を取り除くのは良い事です。

また、クラスのインスタンス(実体)がどれほどのサイズになるか見当がつかないこともあり、スタック領域の消費を考えると、やはりフリーストアを使うためにも動的に確保すると良いでしょう。

余談

突然ですが以下のコードは有効でしょうか。

int a[10];

//~~中略~~

int main(){
  a[2] = 10;
  3[a] = 15; //!?
  //~~後略~~  
}

結論から言うと…有効です。問題ありません。アホですが。

配列はポインタと深いつながりがあります。 配列名は配列の先頭アドレスを指すポインタである ということはご存知でしょうか。
そのため、
a[0]*aは同値です。
同様に、
a[1]*(a+1)も同値です。
※ポインタに対する加減算はポインタの型の分だけ飛ばされる(この場合は多くの環境で4byte増えます)

ともあれ、この性質より[]には、 「ポインタに[]をつけることで、([]の内側に書いた値だけ飛ばした領域にある)メモリを間接参照する」 という性質があるということが読み取れます。
これを踏まえて、以下のように変形ができます。

a[4];
*(a + 4);
*(4 + a);
4[a];

4という値をポインタとして解釈するのです。そしてaという値だけメモリを読み飛ばせば、確かに配列a5番めの要素にアクセスすることと同じです。
まぁ、やる人はいませんが…。

以上です。

福島大学のオーケストラのエキストラ(賛助)出演をしており、例によってAdCのことを完全に忘れていました。 そろそろ謝っても許されない気がしてきた。

f:id:wolf_cpp:20161220063500p:plain

私、やりました。

次はyumetodoさんらしいです。

スタックをオーバーフローさせる話 【初心者C++er Advent Calendar 2016 - 7日目】

ごめんなさい

エチルアルコールが血管を駆け巡ってる状態の深夜テンションでAdC書くって言って忘れてました。

おことわり

当記事はWindowsのことしか考えていません。
また実行可能ファイルについてはPEフォーマットに基づいて記事を書いています。
同様にメモリ上の構造についても他OSについては無知なので悪しからず。

動機

このツイートの関連で再帰を説明することになるなどしました。 (で、見事に忘れてたわけですが)、再帰について記事を書こうとしたら なぜかメモリの話になってしまいました 、すみません。

再帰とは何か

何かの対象をそれ自体で定義することを再帰(recursion)と呼びます。コンピュータ言語に当てはめると、これは関数がその関数自身を呼び出すことを意味します。 (「独習C 第4版(翔泳社)」より)

関数を書くとき自分自身を呼び出すようにしたものを再帰関数と呼びます。
また、以下のようにお互いがお互いを呼び出すような関数のことを相互再帰と呼んだりします 。

void f() {
    g();
}
void g() {
    f();
}

これら再帰関数では必ずいづれかのタイミングで関数がreturnするよう注意してください。
でないとスタックオーバーフローを起こしてプログラムが異常終了します。

戻ってこない再帰プログラムは当然「意図しない」動作すなわちバグということになりますが、スタックとやらを溢れさせると何が起こるのか。
また、再帰以外でもたまに大きなサイズの配列を確保しようとしてこのバグを生むことがありますね。そもそも、

スタックオーバーフローとは何か???

ということで以下お付き合いください。

プログラムの実行について

PEフォーマットに基づいた実行可能ファイル(.exe/.dll)は大まかに言うと、Windows上で実行するために必要な情報(ファイルヘッダ)と、メモリにロードされ実行されるデータ(プログラム + 変数などのデータ)で成り立っています。
この後者がメモリにロードされてプログラムは動いているわけですが、これは当然ビットの羅列である機械語となっています。
それを便宜上16進数で表すと4bitずつのまとまりになるわけですが、これをニブルと言います。
この、ニブルを2つ組み合わせることでIntel 8086系統と呼ばれる今出回っているほとんどのCPUに命令を行うことができます(そのため8bitのかたまりを特別に「バイト」と呼んでいます)。
Intel® 64 and IA-32 Architectures Software Developer Manuals

当然、これらの命令はCPUと、レジスタというCPU内の極小かつ最速の記憶装置を扱うものですので、高度な構文は用意されていません。
もちろんループ構文も関数という概念もありません。代わりにGotoに似たいくつかの構文を組み合わせて実現しています。

おまけのメモリの話

前述したように1命令が1byteだからか、メモリは1ブロック=1byte=8bitとなっています。
32bitアプリケーションにおいてはメモリアドレスは32bit(4byte/16進八桁)で管理しているため、その最大値4294967295byte≒4GBまでしか(仮想/物理)メモリを扱うことができません。

カーネルの使用領域を含めて考えたとき、32bit版OSにおいて「およそ3GBが限界でこれ以上は認識しない」というのはこれが原因です。

仮想メモリ

機械語では基本的にはメモリに読み込まれた命令を上から下に順に実行を行います。
条件分岐は特定のメモリアドレスに実行を移動し、必要に応じて戻る(再度移動を行う)というかたちで実現しています。

しかし実際のコンピュータにおいてはそれらプログラムのデータがメモリのどこに読み込まれるかわかりません。
このため多くのOSでは仮想メモリという仕組みを利用しています。 ざっくりと言うと、プログラムは皆0x00400000を起点として動作することにして、全てのプログラムには物理搭載メモリと同じだけのメモリ領域を与えるという事になっています。仮想メモリと物理メモリの対照はOSに任せ、実際には不連続なメモリを効率良く使うことができるようになっています。この仕組みではメモリが溢れることもありえますが、必要に応じてスワップ(HDDやSSDなどをメモリとして扱う)するなどすることになっています。
※ なぜ0x400000なのか?予約領域ということで保険をかけたのだろう…。深い意味はないのかもしれない。

ヒープとスタック

スタックは後述しますが、事前にメモリ領域を確保した上で、整然とデータを蓄積・解放することができるので高速にアクセスができます。
その性質上、仮想メモリの末尾の方にスタック領域としてまとめて配されるようになっているようです。

一方ヒープは任意のサイズのデータを任意の順番で確保・解放することができます(プログラムの命令ではない部分のデータの保管に向いている)。
newしたときはこちらの方式で確保が行われるのでメモリの限界までデータを確保できるでしょう(現実的には物理メモリの動作を考えたときの制約がありますが)。

コールスタック(いわゆるスタック)

コールスタックとは実行中の関数に関する情報を格納しておく(メモリ上の)部分を指して言います。
スタックという構造をご存じの方にはお分かりいただけると思いますが、これは積み重なるようにデータを格納し、最後に入れたものが先に取り出されます。
関数の呼び出しも同じように、関数が呼ばれたら、前の関数はそのまま置いておいて新たに(重ねるようにして)呼び出された関数を実行します。returnして関数の実行が終わったらその階層のことは忘れて、何事もなかったかのようにして先の関数の続きに制御が移る、というこの制御の移り変わりはまさに「後入れ先出し(LIFO……Last In First Out)」とイメージできます。

このコールスタックは関数が呼ばれるごとに「積み重なるよう」に情報が蓄積していきます。
まずはどんな情報が扱われるのか具体的に見ていきましょう。

リターンアドレスの格納

先ほど、機械語における条件分岐はアドレスの移動で実現すると言いました。C,C++の関数に当たる部分も同様にアドレスの移動でそれを実現していますが、関数の実行が終了して続きを実行するために呼び出し元のどこに戻ればいいのか覚えておかねばなりません(どこから呼ばれたのか覚えておくということ)。 これをリターンアドレスと言い、呼ばれるごとに変わるのでスタックに格納されます。

ローカル変数・引数の格納

スタックは後入れ先出しと言いました。このためスタックに最後に入れたデータ領域を拡張するのは容易くできます。つまり現在実行中の関数についてはスタックの限界を超えない限り高速にメモリを確保することができます。
※ヒープでは、物理メモリ上の使える位置を探してからそれを他のプログラムが使わないような手続きを行ったあとに確保されるので手間がかかります 。

thisポインタ

各メソッドのインスタンスを指すことでメンバにアクセスすることができます。

スタックのサイズ (ここ重要)

スタック領域はVisual Studioのデフォルトではわずか1MB程度(0x000FF000)に設定されているため、できるだけヒープでメモリを確保してそこにデータを格納するべきです。
ちなみに1MBの大きさについてですが、int(4bitと仮定)にしておよそ25万要素程度です。
競技プログラミングにおいて、ローカル変数を避けヒープで確保されるグローバル変数を多用するのはこのためです。

また、同様に、関数を極めて大量に呼び出した場合、これ以上関数が呼べなくなることがあります。
これがスタックオーバーフロー という事象の正体となります。

f:id:wolf_cpp:20161210065301p:plain

テスト

/*
関数 foo は第一引数から第二引数までの整数を出力します。
*/
#include <iostream>

void foo( const int& i, const int& j );

void foo( const int& i, const int& j ) {
    std::cout << i << std::endl;
    if ( i > j ) {
        foo( i-1, j );
    } else if ( i < j ) {
        foo( i+1, j );
    } else {
        std::cout << std::endl;
    }
    return;
}

このコードで適当に大きな値をセットして再帰呼び出しをテストしてみたところ、4140回目あたりの呼び出しでスタックオーバーフローを起こしました。
アセンブラによるとコールスタック1回分のサイズはおおよそ200byte弱程度でした。
案外脆いものですね。

f:id:wolf_cpp:20161210065407p:plain

余談

Visual Studioのリンカオプションでスタックのサイズの設定ができました
試しに100倍に設定してぶん回してみましたが狙い通りしっかりと動いてくれました。

おしまい

遅れてすみませんが、初心者C++er AdC 12/7の記事は以上とします。次はバンビちゃん@実際無職【初心者C++er Advent Calendar 2016 8日目】関数テンプレートと関数オブジェクトです。