c++初歩的な質問ですが教えて頂けると助かります
c++初歩的な質問ですが教えて頂けると助かります
c++を勉強(練習)しています。
とりあえずずっと謎なことがあるので教えていただければ助かります。
1.main関数の中には別の関数を作れないのでしょうか?
2.main関数から別の関数を呼び出す場合は、main関数は一番最後に書いて置かないと動きませんか?
3.main関数以外に関数がある場合(例えば関数A)で、両方で使われる変数がある場合はglobal変数として?冒頭、つまり全ての関数の外で、定義しとかないとどうしても動きませんか?
4.使っている問題集で、main関数の中最後に標準出力puts、coutがあるかと思えば、別の呼び出される関数(最後によびだされる関数)の中に標準出力が書かれていたりします。どちらでも同じですか?
4つとも、何度か試してみたものの、未解決の疑問です。そもそも出来ないことを試しているということも考えられ、質問しようと思った次第です。
よろしくおねがいします。
とりあえずずっと謎なことがあるので教えていただければ助かります。
1.main関数の中には別の関数を作れないのでしょうか?
2.main関数から別の関数を呼び出す場合は、main関数は一番最後に書いて置かないと動きませんか?
3.main関数以外に関数がある場合(例えば関数A)で、両方で使われる変数がある場合はglobal変数として?冒頭、つまり全ての関数の外で、定義しとかないとどうしても動きませんか?
4.使っている問題集で、main関数の中最後に標準出力puts、coutがあるかと思えば、別の呼び出される関数(最後によびだされる関数)の中に標準出力が書かれていたりします。どちらでも同じですか?
4つとも、何度か試してみたものの、未解決の疑問です。そもそも出来ないことを試しているということも考えられ、質問しようと思った次第です。
よろしくおねがいします。
Re: c++初歩的な質問ですが教えて頂けると助かります
1は私ではわかりません・・・
試しにやってみたら↓は動きました
2、mainより上に宣言を書けば問題ないです。
3、?よくわかりません、質問が・・・
関数の中で宣言してそれを別の関数の中でも使える(書きかえれる)か?という意味ならポインタを使えば使えます。
(他にもあった気がするけど・・・)
それとも同じ”名前”の変数を使っても大丈夫か?ということなら問題ないです。
その変数たちは全く関係ない変数です。
4、それが最後の処理?なら同じだと思いますが・・・
状況がわからないとわかりません。
===
何か勘違い書いてたらすいません・・・
試しにやってみたら↓は動きました
#include<stdio.h>
int main(void){
int pako_kannsuu(void);
pako_kannsuu();
return 0;
}
int pako_kannsuu(void){
printf("pakoneko\n");
return 0;
}
#include<stdio.h>
//宣言
int pako_kannsuu(void);
//メイン
int main(void){
pako_kannsuu();
return 0;
}
//行いたい処理
int pako_kannsuu(void){
printf("pakoneko\n");
return 0;
}
関数の中で宣言してそれを別の関数の中でも使える(書きかえれる)か?という意味ならポインタを使えば使えます。
(他にもあった気がするけど・・・)
それとも同じ”名前”の変数を使っても大丈夫か?ということなら問題ないです。
その変数たちは全く関係ない変数です。
4、それが最後の処理?なら同じだと思いますが・・・
状況がわからないとわかりません。
===
何か勘違い書いてたらすいません・・・
ニャン!!\(゜ロ\)(/ロ゜)/
Re: c++初歩的な質問ですが教えて頂けると助かります
素早い返信ありがとうございますパコネコ さん。
int a = 0;
int main(){
int pako(){
○○○
}
a = pako();
}
みたいなのです。無理でしょうか。まあ、関数を並べる書き方に慣れれば、そっちで書けばいい話かもしれませんが。
なので、関数が2個以上ある場合は、2個以上の関数で使われる変数は全てプログラムの冒頭でglobal変数として宣言しておかないと行けないのかなと思っているのですが、これは正しいですか?
そういうのではなく、パコネコ さんが書きました:1は私ではわかりません・・・
試しにやってみたら↓は動きました
int a = 0;
int main(){
int pako(){
○○○
}
a = pako();
}
みたいなのです。無理でしょうか。まあ、関数を並べる書き方に慣れれば、そっちで書けばいい話かもしれませんが。
ありがとうございます。パコネコ さんが書きました:2、mainより上に宣言を書けば問題ないです。
そうですね、質問の意味は、今参考にしているプログラム集があるのですが、関数がmain関数1つしかない場合は、ほとんどすべての変数がmain内で宣言されていて、const int MAX_NUM =100 だけがmainより上でぽつんと宣言されています.ですが、関数が2つ以上になると(宣言やmain関数の説明が本では省略されていて)よくわからず、そのまま単に関数だけ別にmainの外に作って呼び出したりしても、その外に作った関数でエラー:変数が定義されていません、って出てしまいました。最初にmain関数で標準入力した変数データをmain以外の関数で使う場合です。パコネコ さんが書きました:3、?よくわかりません、質問が・・・
関数の中で宣言してそれを別の関数の中でも使える(書きかえれる)か?という意味ならポインタを使えば使えます。
(他にもあった気がするけど・・・)
それとも同じ”名前”の変数を使っても大丈夫か?ということなら問題ないです。
その変数たちは全く関係ない変数です。
なので、関数が2個以上ある場合は、2個以上の関数で使われる変数は全てプログラムの冒頭でglobal変数として宣言しておかないと行けないのかなと思っているのですが、これは正しいですか?
Re: c++初歩的な質問ですが教えて頂けると助かります
1.
ローカル関数の定義はできないかと。
ローカルクラスの静的メソッドを使えば似たようなことはできなくもないけど。
3.
単純に関数の引数を使えばいいのではないでしょうか?
ポインタでも参照渡しでも値を設定することは可能ですので。
ローカル関数の定義はできないかと。
ローカルクラスの静的メソッドを使えば似たようなことはできなくもないけど。
int main()
{
struct Hoge {
static int pako() { return 1; };
};
int i = Hoge::pako();
return 0;
}
単純に関数の引数を使えばいいのではないでしょうか?
ポインタでも参照渡しでも値を設定することは可能ですので。
Re: c++初歩的な質問ですが教えて頂けると助かります
1
でやってみたところ「;」をつけろとしつこく怒られました。
なのでこのままでは難しいかと・・・
3
こんな感じでどうでしょうか?
pako_Aの中での変化は元のaには関係ありませんが、
pako_Bの中では変数aのアドレスに書き込んでるため同じ変数として扱えます。 ということでいいでしょうか?
#include<stdio.h>
int main(void){
int pako_kannsuu(void){
printf("pakoneko\n");
return 0;
};
pako_kannsuu();
return 0;
}
なのでこのままでは難しいかと・・・
3
こんな感じでどうでしょうか?
#include<stdio.h>
int pako_A(int);
int pako_B(int *);
int main(void){
int a=50;
pako_A(a);
printf("a=%d\n",a);
pako_B(&a);
printf("a=%d\n",a);
return 0;
}
int pako_A(int a_modoki){
a_modoki+=10;
printf("a_modoki=%d\n",a_modoki);
return 0;
}
int pako_B(int *a_modoki){
*a_modoki+=10;
printf("a_modoki=%d\n",*a_modoki);
return 0;
}
pako_Bの中では変数aのアドレスに書き込んでるため同じ変数として扱えます。 ということでいいでしょうか?
ニャン!!\(゜ロ\)(/ロ゜)/
Re: c++初歩的な質問ですが教えて頂けると助かります
パコネコ さん、Blue さん、返信ありがとうです。
ポインタを使うなどでmain関数内で宣言した変数でも他の関数で使用可能ということですね。
とりあえず、ポインタはよくわかってないので、頭にとめておき、慣れてきたら試してみます。
ありがとうございます。
ところで、
これなら動くのですが、このmain関数をbinary_search関数の上に持ってくると、デバッグでエラーが出ます。main関数内のsolve();の行で。宣言されてないと。
ですから、main関数を一番上に持って来れないのです。
上に置けるとのことですが、どうしたらいいのでしょうか?
よろしくおねがいします。
ポインタを使うなどでmain関数内で宣言した変数でも他の関数で使用可能ということですね。
とりあえず、ポインタはよくわかってないので、頭にとめておき、慣れてきたら試してみます。
ありがとうございます。
ところで、
#include <iostream>
#include <algorithm>
const int MAX_NUM = 1000;
int n,m;
int k[MAX_NUM];
bool f = false;
bool binary_search(int x){
int l =0, r =n;
while((r-l)>=1){
int i = (l+r)/2;
if(k[i] == x) return true;
else if(k[i] < x) l=i+1;
else r=i;
}
return false;
}
void solve(){
using namespace std;
//sort for binary search
sort(k, k + n);
for (int a=0; a<n; a++) {
for (int b =0; b<n; b++) {
for (int c =0; c<n; c++) {
//binary search instead of 4th loop
if(binary_search(m-k[a]-k[b]-k[c])){
f = true;
}
}
}
}
if(f) puts("yes");
else puts("no");
}
int main () {
using namespace std;
// int n,m;
// int k[MAX_NUM];
cin >> n >> m;
for(int i = 0; i <n; i++){
cin >> k[i];
}
solve();
return 0;
}
これなら動くのですが、このmain関数をbinary_search関数の上に持ってくると、デバッグでエラーが出ます。main関数内のsolve();の行で。宣言されてないと。
ですから、main関数を一番上に持って来れないのです。
上に置けるとのことですが、どうしたらいいのでしょうか?
よろしくおねがいします。
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: c++初歩的な質問ですが教えて頂けると助かります
以下でできるはずです。
プロトタイプ宣言をすることで、「こういう名前の関数がありますよー」ということを先に言っておいてあとから中身を定義することができます。
プロトタイプ宣言をすることで、「こういう名前の関数がありますよー」ということを先に言っておいてあとから中身を定義することができます。
#include <iostream>
#include <algorithm>
const int MAX_NUM = 1000;
int n,m;
int k[MAX_NUM];
bool f = false;
// プロトタイプ宣言
bool binary_search(int x);
void solve();
int main () {
using namespace std;
// int n,m;
// int k[MAX_NUM];
cin >> n >> m;
for(int i = 0; i <n; i++){
cin >> k[i];
}
solve();
return 0;
}
bool binary_search(int x){
int l =0, r =n;
while((r-l)>=1){
int i = (l+r)/2;
if(k[i] == x) return true;
else if(k[i] < x) l=i+1;
else r=i;
}
return false;
}
void solve(){
using namespace std;
//sort for binary search
sort(k, k + n);
for (int a=0; a<n; a++) {
for (int b =0; b<n; b++) {
for (int c =0; c<n; c++) {
//binary search instead of 4th loop
if(binary_search(m-k[a]-k[b]-k[c])){
f = true;
}
}
}
}
if(f) puts("yes");
else puts("no");
}
Re: c++初歩的な質問ですが教えて頂けると助かります
bool binary_search(int);
をメインの上に置いておけばメインより下に
bool binary_search(int x){
・・・
}
としてもエラーでないはずです・・・
こんな感じ?
私の使ってるものでは、インクルードできなかったので起動してませんが・・・
おそらくできるはず・・・
===
すいませんかぶってました・・・
をメインの上に置いておけばメインより下に
bool binary_search(int x){
・・・
}
としてもエラーでないはずです・・・
こんな感じ?
#include <iostream>
#include <algorithm>
//関数の宣言
void solve(void);
bool binary_search(int);
const int MAX_NUM = 1000;
int n,m;
int k[MAX_NUM];
bool f = false;
int main () {
using namespace std;
// int n,m;
// int k[MAX_NUM];
cin >> n >> m;
for(int i = 0; i <n; i++){
cin >> k[i];
}
solve();
return 0;
}
bool binary_search(int x){
int l =0, r =n;
while((r-l)>=1){
int i = (l+r)/2;
if(k[i] == x) return true;
else if(k[i] < x) l=i+1;
else r=i;
}
return false;
}
void solve(){
using namespace std;
//sort for binary search
sort(k, k + n);
for (int a=0; a<n; a++) {
for (int b =0; b<n; b++) {
for (int c =0; c<n; c++) {
//binary search instead of 4th loop
if(binary_search(m-k[a]-k[b]-k[c])){
f = true;
}
}
}
}
if(f) puts("yes");
else puts("no");
}
おそらくできるはず・・・
===
すいませんかぶってました・・・
ニャン!!\(゜ロ\)(/ロ゜)/
Re: c++初歩的な質問ですが教えて頂けると助かります
どうもありがとうございます。
関数の型の宣言を重複してするようで少し違和感がありますが、そういう仕様なのですね。
これですっきり解決しました。
ところで、ついでにあと一つだけ聞きたいことがあります。
プログラミングというよりアルゴリズムの質問になってしまいますが。
binary search(2分探索)では長さnのソート済み配列kに数xが含まれているかを確かめる場合、log2 n(2は下付き)回の繰り返しで済み、結果、計算量はO(log n)となるそうですが、このlog2n(2は下付き)はどういう計算で出てきたのでしょう?
下付きの2は、毎回2分する2から来ているように想像できますが、それくらいしか思いつきません。
ご存知でしたら教えてください。
関数の型の宣言を重複してするようで少し違和感がありますが、そういう仕様なのですね。
これですっきり解決しました。
ところで、ついでにあと一つだけ聞きたいことがあります。
プログラミングというよりアルゴリズムの質問になってしまいますが。
binary search(2分探索)では長さnのソート済み配列kに数xが含まれているかを確かめる場合、log2 n(2は下付き)回の繰り返しで済み、結果、計算量はO(log n)となるそうですが、このlog2n(2は下付き)はどういう計算で出てきたのでしょう?
下付きの2は、毎回2分する2から来ているように想像できますが、それくらいしか思いつきません。
ご存知でしたら教えてください。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: c++初歩的な質問ですが教えて頂けると助かります
>1.main関数の中には別の関数を作れないのでしょうか?
関数内関数は基本的に作れません。
他言語ではサポートされているものも多数あります。
>2.main関数から別の関数を呼び出す場合は、main関数は一番最後に書いて置かないと動きませんか?
関数をプロトタイプ宣言すれば順番は関係有りません。
>3.main関数以外に関数がある場合(例えば関数A)で、両方で使われる変数がある場合はglobal変数として?冒頭、つまり全ての関数の外で、定義しとかないとどうしても動きませんか?
そうなります。
あるいは、引数渡しを使います。
>4.使っている問題集で、main関数の中最後に標準出力puts、coutがあるかと思えば、別の呼び出される関数(最後によびだされる関数)の中に標準出力が書かれていたりします。どちらでも同じですか?
よく分からないので例を挙げてください。
関数内関数は基本的に作れません。
他言語ではサポートされているものも多数あります。
>2.main関数から別の関数を呼び出す場合は、main関数は一番最後に書いて置かないと動きませんか?
関数をプロトタイプ宣言すれば順番は関係有りません。
>3.main関数以外に関数がある場合(例えば関数A)で、両方で使われる変数がある場合はglobal変数として?冒頭、つまり全ての関数の外で、定義しとかないとどうしても動きませんか?
そうなります。
あるいは、引数渡しを使います。
>4.使っている問題集で、main関数の中最後に標準出力puts、coutがあるかと思えば、別の呼び出される関数(最後によびだされる関数)の中に標準出力が書かれていたりします。どちらでも同じですか?
よく分からないので例を挙げてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: c++初歩的な質問ですが教えて頂けると助かります
softya(ソフト屋)さん、返信ありがとうございます。softya(ソフト屋) さんが書きました: 他言語ではサポートされているものも多数あります。
関数をプロトタイプ宣言すれば順番は関係有りません。
そうなります。
あるいは、引数渡しを使います。
よく分からないので例を挙げてください。
分かりました。
4については、私のNo6のポストに添付のコードを参照ください。
そこでは、solve関数に
if(f) puts("yes");
else puts("no");
と書かれているのですが、これをmain関数の最後(solve();行の直後)に持ってきても、同じことかどうかということです。私が手本にしている本に載ってるこのプログラムではsolve内にありますが、これは何かこだわりがあってそうしているのか、それとも定番の表記法だからか、たまたまか、という質問です。
よろしくおねがいします。
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: c++初歩的な質問ですが教えて頂けると助かります
バイナリサーチの特徴は、二分を繰り返していくところです。うしくん さんが書きました: binary search(2分探索)では長さnのソート済み配列kに数xが含まれているかを確かめる場合、log2 n(2は下付き)回の繰り返しで済み、結果、計算量はO(log n)となるそうですが、このlog2n(2は下付き)はどういう計算で出てきたのでしょう?
下付きの2は、毎回2分する2から来ているように想像できますが、それくらいしか思いつきません。
ご存知でしたら教えてください。
二分を繰り返すということは、文字どうり2で割っていくということです。
で、操作回数は長さn'が1になった時の2で割った回数です。
m回の操作で、nの長さまで調べられるといった風に言い換えると
1回の操作で、2
2回の操作で、4
3回の操作で、8
4回の操作で、16
といった風になります。
このとき、nに注目すると、
2, 4, 8, 16, ...となり、2のm乗となります。
よって、mはlog2(n)で求められます。
- bitter_fox
- 記事: 607
- 登録日時: 13年前
- 住所: 大阪府
Re: c++初歩的な質問ですが教えて頂けると助かります
fはグローバル変数なので、fの値はsolve関数を出ても保持されているので、slove();の次に持ってきても問題はないです。うしくん さんが書きました: そこでは、solve関数に
if(f) puts("yes");
else puts("no");
と書かれているのですが、これをmain関数の最後(solve();行の直後)に持ってきても、同じことかどうかということです。私が手本にしている本に載ってるこのプログラムではsolve内にありますが、これは何かこだわりがあってそうしているのか、それとも定番の表記法だからか、たまたまか、という質問です。
関数の処理をどこで分けるかは非常に難しい問題ですね。
今回は、solve関数で出力までの処理を完結させたかったので関数内で出力をしたのでしょう。
ただ、これだと、他の文字列を表示させたかったり、真偽で場合分けしたかったりした場合は、solve関数をいじらなければならいのであまりよろしくありません。
またグローバル変数を使ってるというのも、どこからでも値を変えられたりしてよろしくありません。
trueかfalseをただ単に返すだけにして、あとは呼び出し元任せにした方がよいと思います。
Re: c++初歩的な質問ですが教えて頂けると助かります
bitter_foxさん
バイナリサーチの説明ありがとうございます。対数と指数をネットでしらべてなんとか感覚はつかめました。
no11にもお答えいただき感謝です。
バイナリサーチの説明ありがとうございます。対数と指数をネットでしらべてなんとか感覚はつかめました。
no11にもお答えいただき感謝です。
Re: c++初歩的な質問ですが教えて頂けると助かります
既に納得しておられるようですが、うしくん さんが書きました:どうもありがとうございます。
関数の型の宣言を重複してするようで少し違和感がありますが、そういう仕様なのですね。
これですっきり解決しました。
bool binary_search(int);
これは関数のプロトタイプ宣言(Declarations)です。
bool binary_search(int x){
・・・
}
これは関数の定義(Definitions)で、宣言ではありません。従って重複しているわけではありません。
関数が使用時に既に定義されていれば(main関数が後ろにある場合)宣言なしにそのまま使用できますが、
定義されていない場合(main関数が前にある場合)には関数プロトタイプ宣言が必要です。
C言語ではプロトタイプ宣言なしで使用することもできますが、引数、型のチェックが行われないので、
その後の処理が保障されません。
Re: c++初歩的な質問ですが教えて頂けると助かります
引用失敗してたらすいません4.使っている問題集で、main関数の中最後に標準出力puts、coutがあるかと思えば、別の呼び出される関数(最後によびだされる関数)の中に標準出力が書かれていたりします。どちらでも同じですか?
main()関数の最後で puts,cout を呼び出すのと
main()関数の最後で 別の関数を呼び出し、そこでputs,cout を呼び出すのは同じことか?
ということでしょうか?
標準出力に出力するという点においては同じです
puts,cout を呼び出すタイミング(位置)は異なります(これはわりますよね?)
別の意味でしたらすいません
Re: c++初歩的な質問ですが教えて頂けると助かります
C++であれば関数内関数(のようなもの)は次のように作れます。
functor(ファンクタ)は()演算子のオーバーライドを利用しています。このようなクラス(のインスタンス)は関数オブジェクトと呼ばれます。
lambda(ラムダ)式は簡単に関数オブジェクトの定義できるようにC++0xで採用されることになっています。
Visual C++は2010、gcc(g++)は4.5以降(要-std=c++0xオプション)でコンパイルできます。
#include <iostream>
int main()
{
struct {
int operator()(int a, int b) {
return a + b;
}
} functor;
auto lambda = [](int a, int b) {
return a + b;
};
std::cout << functor(12, 34) << std::endl;
std::cout << lambda(56, 78) << std::endl;
return 0;
}
lambda(ラムダ)式は簡単に関数オブジェクトの定義できるようにC++0xで採用されることになっています。
Visual C++は2010、gcc(g++)は4.5以降(要-std=c++0xオプション)でコンパイルできます。
Re: c++初歩的な質問ですが教えて頂けると助かります
解決ってのを押しとくのを忘れてました。
ISLeさん、dicさん、 maruさん、補足説明ありがとうございました。とても勉強になりました。
ISLeさん、dicさん、 maruさん、補足説明ありがとうございました。とても勉強になりました。
Re: c++初歩的な質問ですが教えて頂けると助かります
解決済みのようですが失礼します
うしくんさんの使用している本とは,「プログラミングコンテスト チャレンジブック」でしょうか?
(違っていたら以降は無視してください.トピ汚しすいません…)
もしそうであればその本の13ページに書いてある
「本質から外れるため、この本では入力はすべてmain関数で読み込まれてグローバル変数に置かれたのち、
関数solveが呼ばれることによって問題を解く形式を用いることにします。」
の文章がいくつかの質問に対する答えになると思います.
つまり,solve関数内で出力をしているのも,グローバル変数を用いているのも,その本におけるルールに乗っ取った結果だと思われます
うしくんさんの使用している本とは,「プログラミングコンテスト チャレンジブック」でしょうか?
(違っていたら以降は無視してください.トピ汚しすいません…)
もしそうであればその本の13ページに書いてある
「本質から外れるため、この本では入力はすべてmain関数で読み込まれてグローバル変数に置かれたのち、
関数solveが呼ばれることによって問題を解く形式を用いることにします。」
の文章がいくつかの質問に対する答えになると思います.
つまり,solve関数内で出力をしているのも,グローバル変数を用いているのも,その本におけるルールに乗っ取った結果だと思われます