C言語をメインで学習しているのですが、
よく変数の初期化のためにわざわざinitという関数を作って、それをmainの中で実行しているサンプルを見ます。

これだと変数はグローバル変数として宣言しなければいけませんし、init関数なんて作らなくても普通に変数をmainの中で宣言して、同時に初期化すれば良いのではと思ってしまいます。

一体何のためにわざわざinit関数を作るのでしょうか?


また、別の質問なのですが、ポインタを使えばグローバル変数を使う必要はないような気がしていて、逆にポインタを使うのが面倒なときでも、グローバル変数で代用できてしまう気がします。
それぞれを使うときのメリット、デメリットがあれば教えていただきたいです。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

>これだと変数はグローバル変数として宣言しなければいけませんし



原因と結果が逆です。

「init関数で初期化する為に、変数をグローバルにする」のではありません。

「どうしてもグローバルにしなきゃならない変数があるから、init関数でまとめて初期化する」のです。

>一体何のためにわざわざinit関数を作るのでしょうか?

初期化処理を1回しか行わないなら、関数にする必要はありません。

しかし、初期化処理を1回しか行わないとは限りません。

例えば「処理のすべてを破棄してプログラムをリスタートする必要が出たら、中断のための後始末をしてから、init関数を呼んでおけば大丈夫」と言う作り方が可能になります。

また、プログラムによっては「一連の処理が終了したら、最初に戻って、すべてを初期状態に戻して、次の一連の処理を繰り返す」と言う場合にも「すべてを初期状態に戻す場合にはinit関数を呼んでおけば大丈夫」と言う作り方が可能になります。

>init関数なんて作らなくても普通に変数をmainの中で宣言して、同時に初期化すれば良いのではと思ってしまいます。

mainで宣言した変数はmainの中でしか使えません。

mainから呼んでいるsub関数の中で、mainで宣言した変数にアクセスする事は出来ません。

「mainの中」や「subの中」や「subから呼んでるsub_subの中」など、あっちこっちで変数にアクセスする場合は
・グローバル変数にして、どこからでも自由にアクセスする
・変数のポインタを関数に渡して、渡された引数のポインタにアクセスする
・変数のポインタをグローバル変数にして、ポインタ経由でアクセスする
などの方法が必要です。

>また、別の質問なのですが
>それぞれを使うときのメリット、デメリットがあれば教えていただきたいです。

つまり
・グローバル変数にして、どこからでも自由にアクセスする
・変数のポインタを関数に渡して、渡された引数のポインタにアクセスする
の2つの場合のメリット、デメリットって事ですね?

グローバル変数にした場合、どこからでも自由にアクセス出来ますが、再帰関数では使用できません。また、関数の汎用性が落ちます。

変数のポインタを引数渡しにした場合、呼び出しごとにポインタを指定する手間は増えますが、再帰関数でも使用できます。また、呼び出し時のポインタを切り替えれば関数を汎用的に使う事も出来ます。
    • good
    • 0
この回答へのお礼

分かりやすい回答ありがとうございます。

グローバル変数を使うからinit関数を使うんですね。
これですっきりしました。


>mainで宣言した変数はmainの中でしか使えません。

例としてmain関数を挙げただけで、各関数内で宣言、初期化という意味です。
誤解を招く表現で申し訳ないです。


確かにグローバル変数では再帰関数は作れませんね。思いつきませんでした。
やはり関数の汎用性を考えるとポインタを使うべきですよね。

お礼日時:2009/05/13 23:05

>よく変数の初期化のためにわざわざinitという関数を作って、それをmainの中で実行しているサンプルを見ます。



「よく」見ますか?私は全然見ません。
よっぽど古いサンプルなのか、よっぽど特殊な分野でのサンプルなのか。

おっしゃるように、そういった手法はグローバル変数を使わざるを得なくなるので、最近ではまず見かけない手法だと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
たまたまなのか、近いうちに数例見かけたので、ある程度のレベルになるとinit関数で初期化するのが常識になっているのかと思ったので、今回質問しました。
多くの場合は特に必要がないのですね。

お礼日時:2009/05/13 22:53

C言語を学習しているということで、


あまり深く難しいことは書きませんが…。

>一体何のためにわざわざinit関数を作るのでしょうか?
初期化するタイミングが最初の1度だけではないからじゃ?

例えば…
画像ファイルを1つ読み込んで、変換するプログラムがあるとします。
これを実行すれば、画像ファイルを1つ読み込んで変換したら終了します。
このプログラムを、複数ファイルを読み込んで変換するように拡張しようとしたらどうでしょう??
1つ目の変換時に使用した変数は初期化しなくても大丈夫ですか??

別質問について、
たまにグローバル変数は使ったらダメ的な感じに説明している人もいるのですが、
『必要な時に使用する』ということが大切です。
仮にすべてグローバル変数だったら、どこからでもアクセス出来てしまいますよね。
(つまり、誰でもつかえると…)
モジュール分割され、モジュール毎に開発担当者が異なる場合を考えてみて下さい。
あなたの作った変数が、あなたの意図しないタイミングで初期化されたり変更されたりしますよね。
これだとプログラムの安全性が損なわれてしまいバグの原因にもなってしまいます。
なので、グローバル変数は公開する必要があるもののみ使用すればいいのです。
(公開しても問題がない場合でも、公開する必要がないなら公開しないほうがいい)
プログラム開発では、何を公開して何を非公開にするかまで設計出来ているか否かが大切です。

あとは使わないものをいつまでも保持しないということで、
全てグローバル変数にしたらその領域はいつ解放されるんでしょうか??
考えてみて下さい。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

確かに毎回初期化する場合には有効ですよね。
でもその初期化される変数にはグローバル変数を使わないといけないのでなんか嫌な気がしたんです。
引数があるinit関数はまだ見たことがないので…。


オブジェクト指向的な発想からあまりグローバル変数は使わない方が良いということでしょうか。
プログラムの規模が大きくなるとその辺りの設計まで考えなければいけないんですね。

確かにメモリの節約にも繋がりますね。

あと今思いついたんですが、ポインタを使ったほうが各関数の機能を独立させられますよね。

お礼日時:2009/05/12 23:46

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qエクセルで種類を数える関数が無いのは何故?

エクセルで種類を数える関数が無いのは何故なんでしょうか?

エクセルで種類を数えるには、いくつかの関数を組み合わせるのが一般的ですよね?
直接数える関数が無いのは、訳があるんでしょうか?

Aベストアンサー

>>エクセルで種類を数える関数が無いのは何故なんでしょうか?

やっぱり、そういう関数が必要な方が全体からみたら少数派だと、エクセルの開発者たちが考えているからではないかと思います。
また、既存の関数を組み合わせたら、対処可能だから、無理して新しい関数を作る必要性もない、開発の優先順位が低いって判断もあるでしょうね。

私は、エクセルの表を作ったり、エクセルVBAでプログラムを作ったりしますけど、そういう関数が必要になったことが全くありませんし。

Qポインタ変数が引数に宣言されている関数の使い方。

以前、キュープログラムで”BYTE dequeue(BYTE *x)”というのを作成した際に、この作り方で質問させていただきい、この関数だと、


BYTE dequeue(BYTE *x)
{
if(Head==Tail){
if(QueueState != QSTATE_FULL){
return QSTATE_EMPTY;
}
}
*x=QBuf[Head];

Head=(Head+1)%MAX_BUF_NUM;

return QSTATE_VALID;
}

この関数だと、QueueState = dequeue(&UartSendBuf[i]);というように使用すれば、配列変数のUartSendBuf[i]でiの数値で指定した配列番号のメモリ番地にdequeueしたい値を入れることができ、なおかつ、キュープログラムがちゃんと動作したかのステータス値を戻り値として出力できるということを教わり、戻り値が複数出力できるような関数が作れるので大変便利だなぁと思ったのですが、

ちょっと疑問があるのですが、
QueueState = dequeue(UartSendBuf[i]);
というように&を付けずにこのプログラムを動かした場合、どのような動きをプログラムはしてしまうのでしょうか?

以前、キュープログラムで”BYTE dequeue(BYTE *x)”というのを作成した際に、この作り方で質問させていただきい、この関数だと、


BYTE dequeue(BYTE *x)
{
if(Head==Tail){
if(QueueState != QSTATE_FULL){
return QSTATE_EMPTY;
}
}
*x=QBuf[Head];

Head=(Head+1)%MAX_BUF_NUM;

return QSTATE_VALID;
}

この関数だと、QueueState = dequeue(&UartSendBuf[i]);というように使用すれば、配列変数のUartSendBuf[i]でiの数値で指定した配列番号のメモリ番地にdequeueしたい値を入れることができ...続きを読む

Aベストアンサー

>i = 8;
>QueueState = dequeue(UartSendBuf[i]);
>というようにしてこの関数を使ったとしても、以前の関数の動作と全く同じということになるということでしょうか?

コンパイルでエラーが起こるかどうかはそのコンパイラや書き方に依存するのでそこは軽く
 ANSI C準拠で書いて対応コンパイラならエラーが出るでしょうし
K&R だっけ?でかいたらエラーは出ません

関数コール側の書き方が間違っているというのは変わりありません
( & を付けない以上ポインタを渡してません プログラムとしては期待する結果を得られません)

改造とかかれてますが
>x[0]=QBuf[Head];
のことでしょうか? そのコードであれば
*x=QBuf[Head]; 
と書いているのと同じですので結果は変わりません

例えがよくありませんが
住所と其処に住んでいる居住者の関係をイメージしてください
UartSendBuf[i] と書いた場合はUartSendBuf[i]に入っている数値(居住者)を意味します
&UartSendBuf[i]と書いた場合は住所を意味します
それぞれ意味合いはぜんぜん違います
(まずその違いを理解してください)

もう少しポインタを学習された方がよいのではないかと思います

再度同じようなこと書きますが
配列変数の場合配列の要素書かずに変数名書いた場合その配列の先頭アドレスが渡されます
それが dequeue(UartSendBuf);  と  dequeue(&UartSendBuf[0]); は同じというのを意味します
特定の配列要素のアドレスを渡したい場合は
(&UartSendBuf[j] のように)必ず & と 要素番号 を書く必要があります
UartSendBuf[j] と書くと UartSendBuf[j]に格納されている数値が渡されます
(関数側はそれをアドレスと思い込んで処理を行います)

>i = 8;
>QueueState = dequeue(UartSendBuf[i]);
>というようにしてこの関数を使ったとしても、以前の関数の動作と全く同じということになるということでしょうか?

コンパイルでエラーが起こるかどうかはそのコンパイラや書き方に依存するのでそこは軽く
 ANSI C準拠で書いて対応コンパイラならエラーが出るでしょうし
K&R だっけ?でかいたらエラーは出ません

関数コール側の書き方が間違っているというのは変わりありません
( & を付けない以上ポインタを渡してません プログラムとしては期待...続きを読む

Qエクセルの関数で

エクセルの関数辞典を見ていたら、CUMPRINC関数というのがありました。
しかし、エクセルの「挿入」→「関数」→関数の分類で「財務」というのを選択したのですが、一覧表に載っていません。
どこに載っているのでしょうか?
どうすればこの関数を使えますか?
ちなみにシートの上でやっても関数の反応をしませんでした。

Aベストアンサー

Yahooで検索してみると、参考URLが引っかかりました。

参考になりませんか?

参考URL:http://money-sense.net/doc/20041215_224257.php

Qmainの外に変数 vs ポインタ渡し

C++についての質問です。プログラミング初心者ですが、よろしくお願いします。
最近、関数の外側でも変数を宣言できることを知りました。関数の外側で変数を宣言すると、全ての関数でその変数にアクセスすることができ大変便利なように思います。
「わざわざポインタ渡しなどする必要はないのでは?」と思ってしまいました。
これは何か問題があるのでしょうか?

初心者の言葉で説明しても理解しにくいかと思いますので、例として「足し算するプログラム」を以下に記載します。
ポインタ渡しで書くと、以下のような感じになるかと思います。

//●ポインタ渡し
#include "stdafx.h"
#include <iostream>
void func(int x,int y,int *pans){
*pans = x+y;
}
void main(){
int a=10, b=20, ans;
func(a,b,&ans);
std::cout << ans << std::endl;
}

しかし、mainの外に変数を宣言すれば

//●mainの外に変数
#include "stdafx.h"
#include <iostream>
int a,b,ans;
void func(int x,int y){
ans = x+y;
}
void main(){
a=10;
b=20;
func(a,b);
std::cout << ans << std::endl;
}

ansをポインタ渡しする必要なく、funcの計算結果をansに代入できました。
「●mainの外に変数」のプログラムはどのような問題や危険性を孕んでいるのでしょうか?

以上になります。長文お読みいただきありがとうございました。
よろしくお願いいたします。

C++についての質問です。プログラミング初心者ですが、よろしくお願いします。
最近、関数の外側でも変数を宣言できることを知りました。関数の外側で変数を宣言すると、全ての関数でその変数にアクセスすることができ大変便利なように思います。
「わざわざポインタ渡しなどする必要はないのでは?」と思ってしまいました。
これは何か問題があるのでしょうか?

初心者の言葉で説明しても理解しにくいかと思いますので、例として「足し算するプログラム」を以下に記載します。
ポインタ渡しで書くと、以下のよう...続きを読む

Aベストアンサー

例えば、
機能を追加して
int func0(int x,int y,int z){
ans = x - y ;
return ans -z;
}
を作ります。

void main(){
a=10;
b=20;
func(a,b);
std::cout << ans << std::endl;

int c=func0(30,40,50) ;
std::cout << c << std::endl;
std::cout << ans+c << std::endl;
}

とすると、
std::cout << ans << std::endl;
→ 30
std::cout << c << std::endl;
→ -60
と出力されます。

ということは
std::cout << ans+c << std::endl;
で期待するのは、
ans 30 + c -60 = -30
となりますが、実際には「-70」が出力されます。

これは、func0で途中計算に ans = x - y ; としてしまったため、ansが変わってしまったからです。


この程度の規模なら、管理もできるでしょう。

ですが、例えば、 「std::cout は実はグローバル変数ansを書き換える」なんてことになっていたらどうでしょうか?
標準ライブラリでは、そのようなことが無いように作られていますが、自作プログラムだと、ついうっかりやってしまう可能性があります。
実用的なプログラムとなると、数千~数十万といった行数になってきます。その中から、グローバル変数がどこで使われているか調べるのは並大抵のことではありません。


変数の有効範囲はなるべく狭く。必要なところだけで有効なようにする。
というのが、現在の主流の考えです。

例えば、
機能を追加して
int func0(int x,int y,int z){
ans = x - y ;
return ans -z;
}
を作ります。

void main(){
a=10;
b=20;
func(a,b);
std::cout << ans << std::endl;

int c=func0(30,40,50) ;
std::cout << c << std::endl;
std::cout << ans+c << std::endl;
}

とすると、
std::cout << ans << std::endl;
→ 30
std::cout << c << std::endl;
→ -60
と出力されます。

ということは
std::cout << ans+c << std::endl;
で期待するのは、
ans 30 + c -60 = -30
となりますが、実際には「-70」が出力...続きを読む

Qエクセルの関数 ネスト

エクセルの関数 ネスト

エクセルの関数で、ネストさせるときがあるとおもうのですが、

関数を内側に書いたらよいのか外側に書いたらよいのか分からなくなる時があります。

エクセルの関数に関してわかりやすく書いてあるページなどありますか。

Aベストアンサー

こんばんは

Excel2003までは、ネストが7まで、2007では64までが可能です。
http://www.google.co.jp/search?hl=ja&source=hp&q=excel+%E3%83%8D%E3%82%B9%E3%83%88%E3%80%802003%E3%80%802007&aq=f&aqi=&aql=&oq=&gs_rfai=

「仕様上は可能」でも、複雑なネストは間違いが生じやすいですし、変更もしにくくなります。「出来るだけネストはしない」「適宜、中間結果をセルに出力する」という方法を採った方が、間違いが少なく、柔軟性のあるシステムになると思います。

>エクセルの関数に関してわかりやすく書いてあるページなどありますか。
関数の個別の機能ならば、Webサイトも書籍も多数あるのですが、「組み合わせて使う」というのはその場その場での発想になってしまうと思います。

Qint main()、void main()、void main(void)、int main(void)

今日、大学でC言語の講義の時間、先生が、

#include <stdio.h>

void main(void){

}

と宣言してプログラムを書くと教えていました。
main関数には、
main()
void main()
void main( void )
int main()
int main( void )

と、人によりいくつかの描き方があったりします。
どれが本当は正しいのでしょうか?
void mainはすべきではないとなんかの本で読んだのですが・・。

Aベストアンサー

通称C89という以前の言語規格(現行コンパイラの多くが準拠)では、下記のいずれかが正しい。
int main(int argc, char *argv[])
int main(void)

但し、最新のC言語規格(通称C99)では、
<ISO/IEC9899:1999>
or in some other implementation-defined manner.
</ISO/IEC9899:1999>
となっているので、処理系が戻り値のvoidを認めていればvoidも可。
# 組込み系などで戻り値を使わない環境もあるためでしょうか。

なので、コンパイラのマニュアルで戻り値のvoidにしていい/しろと書いてない限り、
voidは言語仕様的には正しくない。(でも動くものもある)

Qエクセル関数の解読サイトなんてありますか?

エクセル関数の解読サイトなんてありますか?

いつもお世話になっております<(_ _)>

エクセルファイルに関数の入った数式が入力されています。
セルごとに複数の関数が入っていますが、私にはちっともわかりません。

そこで質問です。
こんなとき「エクセル関数を解読」してくれるようなサイトってありませんか?

たとえば検索窓があってそこに「=SUM(S1:S13)」わからなくて困っている関数式を入力。
すると答えの別ボックスに「S1~S13までの数値の合計」と出てくるようなサイト。

それに近いサイトでも良いので知っている方がいらっしゃればぜひ、教えてください<(_ _)>

Aベストアンサー

もし、

=IF(E14="","",IF(O14="",(IF(E14>"18:00"*1,"18:00",E14)-IF(C14<="8:00"*1,"8:00",C14))*24*1300,(IF(E14>"18:00"*1,"18:00",E14)-IF(C14<="8:00"*1,"8:00",C14))*24*1625))

だったら、どういう文章が出て欲しいのでしょうか?

もしE14が空白だったら、
 空白、
そうじゃなかったから、
 もしO14が空白だったら、
  (もしE14が18:00より大きかったら18:00、そうじゃなかったらE14)-(もしC14が8:00以下だったら8:00、そうじゃなかったらC14)×24×1300
 そうじゃなかったら、
  (もしE14が18:00より大きかったら18:00、そうじゃなかったらE14)-(もしC14が8:00以下だったら8:00、そうじゃなかったらC14)×24×1625

って感じですか?
数式をそのまま読解したほうが解りやすくないですか?

Qポインタ変数とポインタのポインタ

ポインタ変数の宣言
char *a[];
をしたとき僕の中では
a[0],a[1]...という、ある文字列A,B,C...の最初のアドレスを指すポインタが、配列になっているものを宣言していると理解していました。

しかしこの次に、ポインタのポインタが出てきました。僕はこれを、
ある変数を指し示すアドレスのアドレスである、と理解しました。

この2つは1つめはいくつかのアドレスを指し示すもの、2つ目は1つのアドレスを指し示すものであるとして、僕の中で異なったものであると理解していましたが、参考書「C標準コースウェア」によると
プログラムにおいて、関数でポインタ配列を受け取るときchar *p[]はchar **pとしてもよい
と書かれており、またその実例として、
(9-5)
#include <stdio.h>
void disp (char *p[],int n){
int i;
for (i= 1;i<n;i++){
printf("%s\n",p[i]);
}
}
int main(void){
char *girl[] = {"Arica","Candy","Lisa"};
disp (girl,sizeof(girl)/sizeof(girl[0]));
return 0;
}
というプログラムが書かれていました。
ここで一気に訳が分からなくなりました。
char *girl[] = {"Arica","Candy","Lisa"};
と宣言されているため、
girl[0]はAricaという文字列の最初のアドレスを指すポインタ、
*girl[0]はAricaという文字列を直接指し示していると解釈しています。
girlは{"Arica","Candy","Lisa"}という文字列の配列の最初のアドレスを指し示していると考えました。
sizeof(girl)を使った時に不思議なのですが、
girlはどのように配列の終わりを理解しているのでしょうか?
(配列の要素数を渡していない点が不思議です。)
また、
disp側が受け取ったのは*girl[]であり、いくつかのポインタの配列ですが、渡したものはgirlという要素数がないポインタ1つだけです。
そして最初の疑問が出てくるわけですが、*p[]を**pと書きかえてみると、
文字列のアドレスを示すgirlという名の1つのポインタを渡すと、pという名のポインタのポインタで受け取るというのも、よくわからなくなっています。
おそらくポインタ配列に対する理解がどこかでずれているようですが、自分でどこがわからないのかわからなくなっています。
どうかご教授ください。

ポインタ変数の宣言
char *a[];
をしたとき僕の中では
a[0],a[1]...という、ある文字列A,B,C...の最初のアドレスを指すポインタが、配列になっているものを宣言していると理解していました。

しかしこの次に、ポインタのポインタが出てきました。僕はこれを、
ある変数を指し示すアドレスのアドレスである、と理解しました。

この2つは1つめはいくつかのアドレスを指し示すもの、2つ目は1つのアドレスを指し示すものであるとして、僕の中で異なったものであると理解していましたが、参考書「C標準コースウェア...続きを読む

Aベストアンサー

おそらく、実際に試してみるのが手っ取り早いでしょう。


> girlはどのように配列の終わりを理解しているのでしょうか?

コンパイラが配列サイズを知っています。下の test2.c をコンパイルしてみれば、コンパイラがサイズを知らない配列は sizeof できないことが分かると思います。


> 文字列のアドレスを示すgirlという名の1つのポインタを渡すと、
> pという名のポインタのポインタで受け取るというのも、
> よくわからなくなっています。

質問者さんご自身が、質問で引用されていた「関数でポインタ配列を受け取るとき」という部分が肝心です。

配列とポインタを、必ずしも同じように扱えるわけではありません。同じように扱える例を先に学ばれてしまったのが混乱の元になっていると思います。下の test1.cとtest3.c、および test1.cとtest4.c を分割コンパイル/リンクしたプログラムを実行して、比較してみてください。

そして test5.c をコンパイル/実行してみれば、関数の仮引数には実引数そのものではなく、コピーが渡されていることが分かると思います。ポインタの配列でも、ポインタのポインタであっても。「関数でポインタ配列を受け取るとき」char *p[]はchar **pとしてもよいのはこのためです。



// ----- test1.c -----
// (要 分割コンパイル)
char *boy[] = {"Dahl", "Dijkstra", "Hoare"};

// ----- test2.c -----
#include <stdio.h>
int main(void){
char *girl[] = {"Arica","Candy","Lisa"};
extern char *boy[];
printf("%zu\n", sizeof(girl)); // サイズは既知
printf("%zu\n", sizeof(boy)); // サイズ不明(コンパイルエラー)
return 0;
}

// ----- test3.c -----
// 配列に正常にアクセスするケース
#include <stdio.h>
int main(void){
extern char *boy[];
printf("%p\n", boy); // 配列の正しいアドレス
printf("%p\n", &boy); // 上と同一のアドレス
printf("%s\n", boy[0]);
return 0;
}

// ----- test4.c -----
// 配列をポインタと同様に扱うと問題を起こすケース
#include <stdio.h>
int main(void){
extern char **boy;
printf("%p\n", &boy); // ポインタ自身のアドレスと見なされる
printf("%p\n", boy); // 余分な評価で、不正なアドレスに
printf("%s\n", boy[0]); // メモリアクセス・エラー
return 0;
}

// ----- test5.c -----
// 配列、ポインタを関数の引数にした場合
#include <stdio.h>
char *girl[] = {"Arica","Candy","Lisa"};
void disp(char *array[], char **pointer){
printf("%p\n", array); // 配列の正しいアドレス
printf("%p\n", &array); // 仮引数 array のアドレス
printf("%p\n", pointer); // 配列の正しいアドレス
printf("%p\n", &pointer); // 仮引数 pointer のアドレス
printf("%s %s\n", array[0], pointer[0]);
}
int main(void){
disp(girl, girl);
return 0;
}

おそらく、実際に試してみるのが手っ取り早いでしょう。


> girlはどのように配列の終わりを理解しているのでしょうか?

コンパイラが配列サイズを知っています。下の test2.c をコンパイルしてみれば、コンパイラがサイズを知らない配列は sizeof できないことが分かると思います。


> 文字列のアドレスを示すgirlという名の1つのポインタを渡すと、
> pという名のポインタのポインタで受け取るというのも、
> よくわからなくなっています。

質問者さんご自身が、質問で引用されていた「関数でポインタ配列を...続きを読む

Qエクセル関数を、書き写して分析できるツールはある?

タイトルの件、質問します。

エクセルの関数を分析する際に、エクセルの数式バーや、セルに入っている関数を
F2を教えて見るのでは、見にくい場合があります。

現在は、私は、メモ帳に関数をコピーして、分析したり、修正したりしています。
エクセルの機能or他ソフトで、関数を分析できるツールはあるのでしょうか??

【エクセルバージョン】
2003、2007

Aベストアンサー

難解な数式を理解したいとき,最も便利に利用できるのは,2003ではツールメニューのワークシート分析にある「数式の検証」です。
2007では数式タブにあります。

メンドクサイ数式のセルで数式の検証を使い,どの関数やどのカッコから計算が進んでいくのかを1ステップずつトレースして理解します。また意図しない結果がどの段階で発生しているのか追跡します。

このやり方は勿論間違った数式(意図しない結果が出てきた場合)を追跡するのにも使いますが,むしろ誰かに教わった「正しい数式」を理解する時に便利な方法です。
そもそも計算が通っていない(たとえばカッコの対応が間違えていて,Enterしても受け付けてくれないようなミスをしている場合)には使えません。



また,数式バーの中で数式の「中」にカーソルを入れて左右の矢印キーでカーソルを動かしていったときに,「(」や「)」をまたいだ瞬間に,対応する「閉じカッコ」「始まりのカッコ」が色つきで強調表示されるのを確認しながら,カッコの対応がまちがえてないかなどを調べるのも簡易な良い方法です。


あまり使わない方法ですが,数式の中で適宜ALT+Enterを打って「セル内改行」してしまい,数式を縦に分解して書いてみるのも整理しやすい方法のひとつです。

難解な数式を理解したいとき,最も便利に利用できるのは,2003ではツールメニューのワークシート分析にある「数式の検証」です。
2007では数式タブにあります。

メンドクサイ数式のセルで数式の検証を使い,どの関数やどのカッコから計算が進んでいくのかを1ステップずつトレースして理解します。また意図しない結果がどの段階で発生しているのか追跡します。

このやり方は勿論間違った数式(意図しない結果が出てきた場合)を追跡するのにも使いますが,むしろ誰かに教わった「正しい数式」を理解する時に便利...続きを読む

Qmain関数の中でパラメータを宣言

c言語で積分をしています。

a~bまで積分する関数を
dobule integral(double (*f)(double), double a, double b)
{
・・・・・・
return s; /*sが計算結果*/
}
としています。


fx=x*x を積分するときは
double fx(double x)
{
return x*x;
}
を用意して、

main()
{
double ans = integral(fx, 0.0, 1.0);
}
という具合で現在やっています。


本題なのですが、
main関数の中でxを宣言して、そのxで同じように積分をしたいのです。
どうすればよいのでしょうか?
良い方法があれば教えて頂きたいです。

Aベストアンサー

No2の方が既に書いてますように、gxを定義して、gxを呼び出す形になると思います。mainの中で、x1=x/3を定義するのは、無理があります。ここでxは、本来、integral関数の中で、a~bまでxを変化させる時の用途で用いられます。従って、integral関数の中でのみ、意味があります。
従って
double gx(double x)
{
double x1;
x1 = x/3.0;
return fx(x);
}
の関数を定義します。
main関数で
ans = integral(gx,0.0,1.0);
とすれば、integral関数の中からgxを呼び出すはずですので、このようにするのが最も素直な方法かと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報