質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

4回答

2070閲覧

C# User.count++; はcountに1を足すという意味ではないのでしょうか?

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/10/19 09:14

ドットインストールでC#入門をやっています。
今は static修飾子の章をやっているのですが、サンプルスクリプトで理解できない箇所があります。
ドットインストールのC#入門は質問を受け付けていないので、こちらに投稿してみました。
説明いただけると大変助かります。

▼サンプルスクリプト

using System; // static class User { private static int count = 0; public User() { User.count++; } public static void GetCount() { Console.WriteLine($"# of instances: {count}"); } } class MyApp { static void Main () { User.GetCount(); User user1 = new User(); User user2 = new User(); User user3 = new User(); User.GetCount(); } }

▼コンソール結果

# of instances: 0 # of instances: 3

■ ひっかかっている箇所

User.count++;
これはcount(ここではインスタンスの数)に1を足すという意味なので
コンソール結果は

# of instances: 1 // count++で初期値0に1が足されるから # of instances: 4 // count++でインスタンス数3つに1が足されるから

になるのではないでしょうか?
++で1を足しているのに、どうして結果が初期値0と作成されたインスタンス数の3つなのかがわかりません。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2021/10/19 09:19

ドットインストールの質問機能をご利用されないのでしょうか。
Zuishin

2021/10/19 09:22

インスタンスやコンストラクタの概念からわかっていないようなので、もっと前からやり直すのが良いと思います。
退会済みユーザー

退会済みユーザー

2021/10/19 09:23 編集

C#入門については「このレッスンは視聴可能ですが、質問の受付や内容の更新は終了しております。」となっており、動画視聴とソースコピーはできますが、有料登録していても、質問はできません。(アーカイブされていない他の講座は質問可能です)
退会済みユーザー

退会済みユーザー

2021/10/20 00:20 編集

質問の前に、まずは自分でデバッグして動きを確認しましょう。 [Visual Studio デバッガーでコード間を移動する] https://docs.microsoft.com/ja-jp/visualstudio/debugger/navigating-through-code-with-the-debugger?view=vs-2019 [超初心者でもわかるデバッグ方法] https://docs.microsoft.com/ja-jp/visualstudio/debugger/debugging-absolute-beginners?view=vs-2019&tabs=csharp [質問するときのヒント] https://teratail.com/help/question-tips > 1-1. teratailはサポートセンターではなく、思考するエンジニアの為のQ&Aコミュニティです > teratailを「サポートセンター」だとは思わないでください。 > 作業依頼のような投稿をして、課題や仕事を無償でやってもらえる場ではありません。 > あなたがそのようなつもりで質問しているのだと他のユーザーから誤解されないように、丁寧な質問を心がけましょう。 思考するエンジニアの為のQ&Aコミュニティです、と書かれているように、無料で初歩から丁寧に教えるような用途のサイトではないので、基礎から段階を踏んだ学習をするなら、入門書を購入して一通り内容をこなしたり、MicrosoftのC#リファレンスを読んだり、メンターサイト等を利用して指導を受けた方がよいと思います。
guest

回答4

0

ベストアンサー

++で1を足しているのに、どうして結果が初期値0と作成されたインスタンス数の3つなのかがわかりません。

何か誤解があるようです。

誤解を整理するためにはメソッドやコンストラクタで行われている処理を呼び出し元に書いてみましょう。
実際に試してみると

C#

1User.GetCount(); 2User user1 = new User(); 3User user2 = new User(); 4User user3 = new User(); 5User.GetCount();

上記の処理は

C#

1int count = 0; 2Console.WriteLine($"# of instances: {count}"); // count : 0 3count++; // count : 0 + 1 4count++; // count : 1 + 1 5count++; // count : 2 + 1 6Console.WriteLine($"# of instances: {count}"); // count : 3

このようになるでしょう。
メソッドやコンストラクタを呼び出していない点以外は大体同じです。
static を絡めるならば下記のようなソースコードと同じです。

C#

1class MyApp 2{ 3 private static int count = 0; 4 static void Main () 5 { 6 Console.WriteLine($"# of instances: {count}"); // count : 0 7 // MyApp.count++; と書いても構いませんが、自身のメンバなら省略できます 8 count++; // count : 0 + 1 9 count++; // count : 1 + 1 10 count++; // count : 2 + 1 11 Console.WriteLine($"# of instances: {count}"); // count : 3 12 } 13}

どうして結果が初期値0と作成されたインスタンス数の3つ

count をインクリメントする前にコンソール出力しているから 0 が表示されています。
count を3回インクリメントした後にコンソール出力しているから 3 が表示されています。

伝えたいこと

このようにメソッドやコンストラクタを使わない形に置き換えることができれば、難しい問題ではありません。
※ もちろん逆(メソッドやコンストラクタを使う形)に置き換えることもできます

dev-milk さんにとってこの置き換えが難しいと感じられるようでしたら、static 修飾子を学ぶ前にクラスとインスタンス・コンストラクタ・メソッド等の使い方や概念を学んでみると良いでしょう。
※ ただし、メソッドやコンストラクタは処理を置き換えるために存在している訳ではなく、それ等の特性上たまたま置き換えられる部分があるだけに過ぎないという点は誤解されないように気を付けてください

学ぶ際は信頼できる情報源に頼ってください。私のおすすめは下記サイトです。
C# によるプログラミング入門

投稿2021/10/20 02:21

編集2021/10/20 02:38
BluOxy

総合スコア2663

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/20 04:27

BluOxyさん 大変わかりやすい説明とフォロー、ありがとうございます!! ここでの count++ は、インスタンスを書いた行の数に1を足すと意味ではなく、 class User に渡された値に1を足すということなので、 class User に渡された値に1を足す × インスタンス記述の回数分 が出力されるということですね。 最初のUser.GetCount();  で結果が0なのは、その前に何も処理されていないし、 private static int count = 0; で初期値を0としているから、で、 次のUser.GetCount();  で結果が3なのは、。; // count : 0 + 1 count++; // count : 1 + 1 count++; // count : 2 + 1 で結果が3と。 理解しました。 ご紹介いただいた、C#によるプログラミング入門で、もう少しじっくりメソッドやクラス、コンストラクタを学習してみます。 ありがとうございました!
guest

0

何がどんな順番で動いているのかを掴みかねている場合には,
以下の例のように,各タイミングがわかるような出力を入れてみればよいでしょう.

Main 内の行間に出力を入れる:

CSharp

1static void Main () 2{ 3 Console.WriteLine( "(1)" ); 4 User.GetCount(); 5 6 Console.WriteLine( "(2)" ); 7 User user1 = new User(); 8 9 Console.WriteLine( "(3)" ); 10 User user2 = new User(); 11 12 Console.WriteLine( "(4)" ); 13 User user3 = new User(); 14 15 Console.WriteLine( "(5)" ); 16 User.GetCount(); 17 18 Console.WriteLine( "(END)" ); 19}

User.User()が実行されるタイミングと,そのときのcountの値が分かるように出力を入れてみる:

CSharp

1public User() 2{ 3 Console.WriteLine( $" 今の値は{count} -> ++する" ); 4 User.count++; 5}

そしたら,こんな出力になるので把握しやすいのではないかと.

(1) # of instances: 0 (2) 今の値は0 -> ++する (3) 今の値は1 -> ++する (4) 今の値は2 -> ++する (5) # of instances: 3 (END)

投稿2021/10/20 05:13

fana

総合スコア11675

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/20 05:21 編集

わざわざコードを汚さずとも、デバッグで一行づつステップ実行して動き見るのが良いのではないかと。 変数の値もリアルタイムで確認出来ますし。
fana

2021/10/20 05:25

デバッガを使うのも良いですが, この程度の内容なのであれば,提示した出力例のように一括で経過が見える方がわかりやすい場合もあるかな,と. あとは,デバッガの利用経験が無いような場合に「とりあえず手っ取り早い」という点が,極微小な利点…かな?
退会済みユーザー

退会済みユーザー

2021/10/20 06:08

radianさん >デバッグで一行づつステップ実行  エラー見ても入力した文字が間違っている(Userのrが他の文字になっているとか)レベルの単純なものならわかりますが、それより内容が濃いとわからないことがほとんどなので無理です。
退会済みユーザー

退会済みユーザー

2021/10/20 06:13

?実行順序を確認するならステップ実行すればいいという話ですが、エラーの話はどこから出てきたのですか?
BluOxy

2021/10/21 02:25 編集

> エラー見ても入力した文字が間違っている(Userのrが他の文字になっているとか)レベルの単純なものならわかります ひょっとしてコンパイルエラーの話をされているでしょうか。 ステップ実行 というのは実行中のプログラムを特定の行が実行されるタイミングで停止でき、ユーザー操作で1行ずつ実行することができる機能です。この機能を使って停止したタイミングにある行で使われている変数の値を確認することができます。 今回でいう count もステップ実行を使うことで特定の行で止めたときの count の値が確認できます。
fana

2021/10/20 06:23

> 極微小な利点 が輝きそう? (新しい物事に関する学習コストを要しない優れた方法なのですぞ)
K_3578

2021/10/20 06:25

質問者がデバッガがどういうものかわかっていないレベルならfana氏の回答はデバッガがどういうものかを知る意味でも良い回答なのではないだろうか(+1)
退会済みユーザー

退会済みユーザー

2021/10/20 06:28

まあVisualStudioのようなIDEが使えないとか、止めれないタイミングで値を記録したい場合はコンソールとかログに出力するしかないでしょうね。ただ、使えるものは使った方が便利だと思います。 (追記・修正依頼欄にもデバッグの仕方のリンク紹介したけど、読んでなさそう)
BluOxy

2021/10/20 06:41

私も Visual Studio を使っているなら1クリックでブレークポイントを置いてステップ実行できるので、そちらをデバッグの手段としておすすめしたいですね。 まあ、手段はどうあれ dev-milk さんにとってやりやすい手段でデバッグを経験するとプログラムへの理解度が上がって楽しいかなと思います
BeatStar

2021/10/20 06:52

私もC言語でいうMinGW, Javaでいうjavacのようなコマンドラインからのやつでやっているときに、デバッガの使い方がわからない間はfanaさんの仰るようにやっていましたね。
Zuishin

2021/10/20 08:04 編集

Visual Studio でブレークポイントを使う場合には、ブレークポイントの丸印を右クリックして編集すると、止まる条件を追加できたり、ブレークポイントを通過した時に止まるのではなく変数の値を加工して出力ウィンドウに出力できたりするので、たとえば 1000 回目のループの値を知りたい時など便利です。 ウォッチ式を使えばステップ実行しながら変数の値を素早く確認できますし、止まったところでイミディエイトウィンドウを開くと、メソッドを呼んだり変数の値を代入できたりします。 たとえば次のようなコード ``` int i = 1; Console.WriteLine(i); ``` この Console.WriteLine(i); の行にブレークポイントを張り、止まったところでイミディエイトウィンドウを開き、i = 5 と打ち込んで次に進めると、コンソールに 5 と出力されます。 これらは回答者の皆さんはご存じでしょうが、デバッガを使ったことのない人には「こんな便利な機能があるよ」と知ってほしいですね。 コーディングにデバッガやテストを使わないのは非常にもったいないと思います。
fana

2021/10/20 08:23

ここで 狂信的アンチデバッガ!みたいなヤバめな感じに振る舞えるだけの演技力が自身に無いことが誠に遺憾. (そういうのがいた方が,質問者にとって有益な情報がたくさん書き込まれそう的な意味で)
Zuishin

2021/10/20 08:31

デバッガと聞くだけで拒絶反応を起こす人がいるし、デバッガに何を使うかによってできることや手順も違うので、デバッグ方法を回答しようと思えば、コードを書き換える方法しか実質できないのが難点です。
退会済みユーザー

退会済みユーザー

2021/10/24 15:14

fanaさん お伝えするのを失念していました。 丁寧な説明をありがとうございます。 こちらに質問してから、もう一度C#の入門講座を1からやってみました。 あと他の回答者の方から教えていただいたC#入門者向け練習問題もやってみました。 少しずつぼやっとですが、みなさんのおっしゃっていることが理解できるようになりました。 ありがとうございました。
guest

0

コンストラクタはインスタンス化を行うときに、オブジェクトが持つフィールドを初期化したり、
前処理(ファイルの入出力なら「ファイルを開く」等) を行います。

つまり、『コンストラクタはインスタンス化のときに動く』です。

class MyApp { static void Main () { // staticなGetCountメソッドを呼び出す User.GetCount(); // インスタンス化 1 User user1 = new User(); // インスタンス化 2 User user2 = new User(); // インスタンス化 3 User user3 = new User(); // staticなGetCountメソッドを呼び出す User.GetCount(); } }

というコードを読むと、

1. 現在のstaticなcountを出力 ( count = 0 なので 0が出力される ) 2. インスタンス化 ( これにより 0 + 1 = 1 -> count = 1 ) 3. インスタンス化 ( これにより 1 + 1 = 2 -> count = 2 ) 4. インスタンス化 ( これにより 2 + 1 = 3 -> count = 3 ) 5. 現在のstaticなcountを出力 ( count = 3 なので 3が出力される )

よって、{ 0, 3 } しか出力されません。


[追記1]

この追記はオフトピですがfanaさんの回答へのコメントで気になったので書いておきます。

質問者さん、エラーの種類は区別した方がいいです。

一般的に(?)言われているエラーには種類があります。
私が分かっている範囲だけでも、数種類ありますね。

一. コンパイルエラー

これはコンパイラが解釈できない事が原因です。
大抵はタイポ(タイプミス)や、構文ミスです。

たとえば int user という変数を使おうとして、usep = 100 としたりとか。
そうなると、『いや、usepってなんやねん。そんなん無いわ』と突っ込まれるわけです。

コンパイラは所詮、機械です。機械は言われた通りにしか解釈できません。
人間だと文脈から『もしかしてuserって書きたかったのか?』と推測してくれますが、機械は言われた通りにしかしないので、「んなもん、ねーよ」と言うのです。

これがコンパイルエラー。compile error ということからもわかりますね。

対応策1: エラーメッセージを読んで対処する 対応策2: コードを読む

エラーメッセージはヒントの宝庫です。つか、コンパイラからのメッセージです。
メッセージを読むことで対処できます。(やりづらいこともあるが、エラーメッセージで検索かければ出てくることが多い)

原因がわかれば対処もできますよね。

二. 例外

これは言語や場合によりますが、「環境によるもの」か「コンパイルエラーでは検出できなかったエラー系」ですね。

たとえば、『ファイルが無い』系、『メモリが足りない』系、「int型に変換できなかった」系…とかですね。

対応策1: エラーメッセージを読んで対処する 対応策2: いわゆる「printfデバッグ」を用いる 対応策3: コードを読む

これもメッセージが出ているので読めば対処できることが多いです。

ちなみに、printfデバッグはC言語のprintf関数から来ています。
C#だと System.Console.Writeメソッドとかでしょうか。

つまり、fanaさんが回答で仰っている通りです。表示する数字を"(1)"ではなく"1" とかみたいにしてもいいですが。

できればデバッガを使う方が望ましいです。ですがVC#を持っていないとかやむを得ない場合もありますし、使い方がよくわからない場合もあります。なので強くは言いませんが、せめてprintfデバッグはできるようにしてください。

三. 論理エラー

これは単純にロジックが間違っているということです。

たとえば、本来なら『合格』と出力されるはずが、なぜか『不合格』となっていたりとか。
そのロジックを追うと、『なぜか値が書き換えられていた』とか、『計算式が間違っている』とか『条件式をミスっている』とかが多いですね。(処理そのものが間違っていることもあるが)

対応策1: デバッガを使う 対応策2: いわゆる「printfデバッグ」を用いる 対応策3: コードを読む

これも一緒です。

四. 急にクラッシュする

これはC#には無いとは思いますが、C言語とかには良くあるので。
C#の場合は急にクラッシュするというより、『例外』が飛んできて…ですが。

対応策1: デバッガを使う 対応策2: いわゆる「printfデバッグ」を用いる 対応策3: コードを読む

五. リンケージエラー

C#では言うのかわかりませんが、C/C++でも、必要なライブラリをリンクせずに実行ファイルを作ろうとすると、『○○っていう関数(メソッド)はねーよ』となります。

必要なライブラリ等を追加していないことが原因です。

対応策1: 公式リファレンス等を読んで必要なものを考え、追加する

六. その他のエラー

たとえば、割と多いのが、『gccやjavac等のようなコンパイラの使い方が間違っている』等でしょうか。
C# であれば cscを直接使ってのコンパイルとかのようにやるとき、存在しないオプションを指定したり、必要なものを指定しなかったりとかすると、cscとかが『なんか変じゃね?』と突っ込みます。でも初心者の方って、これも『エラーが出た(泣』と言ってきます。

そもそも前提が違いますよね。cscとかの問題なのに、コードだけ出されても……

対応策1: そのツールの使い方を学ぶ

……と一言にエラーでも、いろんな種類があり、それぞれ対策が違ってきます。

(fanaさんの回答へのコメントにて)

エラー見ても入力した文字が間違っている(Userのrが他の文字になっているとか)レベルの単純なもの

これはコンパイルエラーですね。

(同じくコメントにて)

それより内容が濃いとわからないことがほとんどなので無理

それは何を示しているかわかりませんが、コンパイルエラー以外のやつですね。

対策はそれぞれ違うので区別しましょう。

投稿2021/10/19 12:33

編集2021/10/20 07:48
BeatStar

総合スコア4958

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2021/10/19 23:53

参考に挙げられたサイトを見て: なぜ、C#の話にC++のサイトを挙げられるのでしょう。それも20年以上前のコンテンツですよ。intro.txtに1998年3月とあります。文字コードの指定もないから、うかつに閲覧すると文字化けします。
BeatStar

2021/10/20 00:23

失礼しました。『(参考)にしたサイト』が抜けていたようです。 文字化けの件もあるので(URLの部分を)削除させていただきます。
退会済みユーザー

退会済みユーザー

2021/10/20 00:26

質問と関係ない部分の説明が多すぎるので、『コンストラクタはインスタンス化のときに動く』から先だけで十分でしょう。
BeatStar

2021/10/20 00:38

@ radianさん ですね…
dodox86

2021/10/20 00:52 編集

[回答が改善されて不要なコメントとなったので削除]
退会済みユーザー

退会済みユーザー

2021/10/20 04:29

BeatStarさん、コメントありがとうございます。 基本がよくわかっていないので、もう一度じっくり基本(フィールド、メソッド、クラス、コンストラクタ..)を学習しなおしてみます。
guest

0

public User() は、new したときに動きます。
初めのUser.GetCount(); の時点では、User.count++;は一度も動いていないので、
instances: 0 であっています。

投稿2021/10/19 09:32

seek

総合スコア32

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/10/20 04:30

seekさん、コメントありがとうございます。 >public User() は、new したときに動きます。<<こう書いてくださるとすっと頭に入ってきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問