ポインタがわかりません。
教えてください。
下の二つは、共に「100」を表記すると思いますが、
どこがどのように違うのですか。
また、f1()という関数をつくって、ここで
scanfを使って、5つぐらい値を代入させて、
他の関数でこの値を使おうと思っています。
この場合下のどちらを使うのが、よろしいのでしょうか。
よろしくお願いします
#include <stdio.h>
int main(void)
{
int *p, q;
q = 100; /* q に100を代入 */
p = &q; /* p にq のアドレスを割り当てる */
printf("%d", *p);
return 0;
}
#include <stdio.h>
int main(void)
{
int *p, q;
p = &q; /* q のアドレスを得る */
*p = 100; /* ポインタを使ってq に値を代入する */
printf("%d", q);
return 0;
}
No.1ベストアンサー
- 回答日時:
無駄なことをやっているように見えますが、これはこのようにする必要があるのでしょうか。
これではポインタを使っている意味が、とくにないでしょう。
int main(void){
int q;
q = 100; /* q に100を代入 */
printf("%d", q);
return 0;
}
このようにできない理由は?
レポート課題?
ただただポインタを使ってみたかった?
ちなみに、あえてどちらの場合が有効かについて。
int変数とポインタ変数に必要な容量は、両方とも4バイトです。
よって、コピーにかかる時間はいっしょです。
intでなくdoubleにすれば、ほんの少し変わるかもしれません。
本当にポインタについて勉強したかったら、ポインタについて解説した本がいくつかあるので、1冊買ったらどうでしょう。
もしくは、オンラインヘルプと数ヶ月にらめっこするだけで、結構わかることもありますよ。
この回答への補足
haporunさんレスありがとうございます。
ただただポインタを使ってみたかった?
そうなんです。ポインタを理解したいだけです。
はじめに書きましたが、scanfで値を入力させて他の関数でその値を使いたいのですが、
retutnで返せるのは、一つだけらしいので、ポインタを使おうと思いました。
また、グローバル変数にすれば簡単ですが・・・。
もちろん、今やろうとしていることも、
別にmain関数だけでかけますが、ポインタを理解するためにやっています。
これは、独習Cから抜粋しただけです。
レポートではありません。独学なので。
よろしくお願いします。
haporunさん、ごめんなさい。
補足の所に書いてしまいました。
>コピーにかかる時間はいっしょです。
ほとんどいっしょですか。
なんとなく解ってきました。
もっと勉強してきます。
ありがとうございました。
No.4
- 回答日時:
deagleさんへ。
上のソースも下のソースも特に問題ないのでは?
両者のポインタp は実際に使用される前に、
両方とも、&qが代入されていますよ。
ただ、deagleさんのおっしゃるように、C/C++は何を指しているかわからないポインタにも値自体は代入できてしまう上、半々ぐらいの確率で実行が成功したり、プログラムがフリーズしたり、OSごと跳んだりするというすごい仕様になっていますので、その点には注意が必要です。
kokucho81さん、またレスありがとうございます。
>両者のポインタp は実際に使用される前に、
>両方とも、&qが代入されていますよ。
注意したいと思います。
レスをつけてくださった皆様へ
いろいろと試してみて、力をつけたいと思います。
ありがとうございました。
No.3
- 回答日時:
あ。
下のソースは駄目です。希にプログラムがハングアップします。変数というのは値を入れた「箱」であり、ポインタは「その箱がどこにあるか」を書いたメモです。
ところが、宣言したばかりのポインタにはどんな値が入っているか分かりません。
そのポインタ変数に値を入れると、「どんな値か分からない」値がアドレスとして使用され、それが偶然にもシステム領域のど真ん中だった場合、こんな簡単なプログラムがシステムメモリを破壊して場合によってはフリーズします。
上のソースは「ポインタ(メモ)にアドレスを書き込む」という動作をしているので問題ありませんが、下は「どこだかよく分からないアドレスに値を書き込む」という動作なので大変危険です。
ちなみにポインタの概念は、C言語を勉強する人が必ず通り壁ですので、すぐには理解できなくても不思議はありません(^_^;
上記の説明で分からないところがあったら補足してください。
No.2
- 回答日時:
ポインタの概念そのものに関する勉強中なのですね。
そうですね。両者は同じ行動ですが、次のように全く同様に比較した方が良いでしょうね。
(1)
int *p, q;
p = &q;
q = 100;
printf("%d", *p);
(2)
int *p, q;
p = &q;
*p = 100;
printf("%d", q);
まぁ、同じですね。
>scanfを使って、5つぐらい値を代入させて、
とりあえず、例えば、
void foo (int a, int b, int c, int d, int e) {
// a,b,c,d,eにscanfで値を代入する
}
という具合に5つほど、入力された値を変数に代入するということであれば、
void foo(int *a, int *b int *c int *d int *e) {
// a,b,c,d,e は格納先を指すポインタ(のはず)である。scanfに&はいらない。
scanf ("%d%d%d%d%d",a,b,c,d,e);
}
int main(void) {
int v1,v2,v3,v4,v5;
foo(&v1,&v2,&v3,&v4,&v5);
}
と「ポインタ」を使用するか
void foo(int &a, int &b, int&c, int &d, int &e) {
// a,b,c,d,e は参照である。scanfに&が必要。
// scanf ("%d%d%d%d%d",&a,&b,&c,&d,&e);
}
int main(void) {
int v1,v2,v3,v4,v5;
foo(v1,v2,v3,v4,v5);
}
と「参照」(アドレス演算子ではないので注意を!)を使用するか
です。
参照を使用したほうが「高速」で、「無駄なメモリも必要ない」ですが、
呼び出し側で「値渡し」との区別がつかない(値を渡すだけか、値が中で変えられてしまうのかは、作った本人以外は使ってみないとわからない)という弱点はあります。
それを補うためには、setValuesOf(...)などというように、値が変更されると言うことが明示的にわかる関数名としておきましょう。
kokucho81さん、レスありがとうございます。
例まで書いていただきまして、ありがとうございました。
いろいろと試してみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# C言語: ポインタ 5 2022/06/01 08:33
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
fopne で失敗する原因
-
init関数の意味
-
C言語のポインタに直接アドレス...
-
CImage GetBitsメソッドについて
-
C言語でのconstを返す関数
-
CWnd::EnableWindow()の扱い方
-
Run-Time Check Failure #3とい...
-
連結リスト 要素の入れ替え
-
main(int argc,char **argv[])...
-
ポインタについて
-
[C言語] NULLは必ず0(番地)です...
-
参照型で受け取った引数をポイ...
-
VBはCを混乱させる?
-
C言語の文字列?処理 strcpyやl...
-
スコープ外でのアドレスの参照...
-
DIBヘッダへのポインタ
-
LPSTR型の初期化について
-
C++で関数ポインタから関数名を...
-
単方向リストの解釈
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
LPSTR型の初期化について
-
Cで作成したDLL関数をVBから呼...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
構造体とfscanf
-
c言語で任意のファイルから読み...
-
デバイスハンドルとは?
-
基本アルゴリズムの『返す』の...
-
main(int argc,char **argv[])...
-
コンストラクタでnewを失敗した...
-
C言語の関数と配列に関する質問
-
ハンドル、アドレス、ポインタ...
-
参照型で受け取った引数をポイ...
-
DLL<->VB間での受け渡し(文字...
おすすめ情報