C言語でのポインターの使い所、どんな時に使うのか、どんな時に役立つのかを教えてください。

A 回答 (3件)

関数で変数を使いますよね。

その変数は関数の持ち物です。
だから、その関数から別の関数にその変数を渡したい時に、その変数自体は渡せません。 自分の物ですから。
仕方が無いので変数のコピーを渡します。 渡した変数は、渡された関数の持ち物です。


変数が荷物だとすると、いちいち荷物の中身を複製して、新しい入れ物を用意して、その入れ物を関数に渡します。
ちょっと面倒ですよね。

ポインタの場合、荷物の中身を複製せずに、ここにあるよという荷札みたいな物だけを渡します。
らくちんですよね。

いろんなことをする時に、荷札だけをやり取りすると楽な場合があります。
メモリ割り当て関数も、どこかに荷物を作って、その荷札だけを渡してくれます。
荷札は簡単に複製できるので、危険はありますが、やり取りが簡単なんです。

簡単にやり取りができないと合理的に使えないアルゴリズムが一杯あります。
それらを使うときにポインタが便利なんです。
    • good
    • 0

配列しかないと、一直線のデータしか表現できません。



ポインタがあると、トーナメント表のようなツリー状のデータ表現や
輪っかのように循環したデータ表現をプログラムで扱えます。

そのようなデータを無理矢理配列に当てはめてもプログラムは作れる
でしょうが、人が考える時の表現をなるべくそのまま扱う方がプログラム
は作り易いですし、間違いが入る余地は少なくなります。
    • good
    • 0

ポインタは、ないと大変困ります。



文字列操作、配列操作の際に実行時に動的に必要な
分だけメモリを確保するため、メモリの使用量は
少なくてすむ場合があります。

デメリットとしては、動的に確保したメモリは
必ず開放する必要があります。
    • good
    • 0

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

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

Qc++言語で、上達に役立つコードを書きたい。 c言語は一通りやって来てます。仕事での使用経験はない

c++言語で、上達に役立つコードを書きたい。

c言語は一通りやって来てます。仕事での使用経験はないです。
基本情報の資格は取ってます

新しくc++を学んだのですが、上達の為に何を作ろうか悩んでます。
以下の条件に合う、要求要件なら何でも知りたいです

・1週間程度で作成出来る
・業務にも応用のききそうな内容

また、参考になるコードあるかもってサイトも、もしご存知でしたら、ぜひ。

Aベストアンサー

下記サイトでスキルを確かめてみるのはどうでしょう。
https://codeiq.jp/

QC言語C++言語アセンブラ言語の就職先

自分は以前Javaプログラマをやってました。

あまりに、便利なライブラリばかりで、「なんかプログラムを書いているというより、ソフトウェアの振る舞いを書いているだけだ。。」とおもってしまい、すきになれませんでした。正直、苦痛でした。

今、上記言語を勉強しているのですが、コンピュータの根本からプログラムをしている実感が沸き、とても面白いです。

でも、これらの言語を習得したところでどんなところに就職できるのかさっぱりわかりませんし、需要があるのかもしりません。いわゆる組み込み系統は就職できるんでしょうが、私としてはアルゴリズムでUNIXのプログラムをシコシコ書いているような作業がすきなのです。いってみれば、私はクラシックな人間だとおもいます。

そんな僕ですが、就職先はあるのでしょうか?よろしくお願いします。

Aベストアンサー

 勉強熱心ですね。
 実際に、kamkamkam3-san の言われている、
「なんかプログラムを書いているというより、ソフトウェアの振る舞いを書いているだけだ。。」というのは的を得ています。
 
 経験からなんですが、ソフトウェア会社では、ノウハウとしてライブラリをもっています。ちょうど、Java のクラス・ライブラリーなようなものです。ですから、それらを使って製品を効率良く製品をつくれるかが重要です。実際のソフトウェア・エンジニアは、それをうまく使って効率良くコーディングすることを要求されます。

 ソフトウェア業界は、1人で閉じた製品を開発することは、まずないです。製品=プロジェクトだとすると、最低3名~100人以上が同時進行となります。そうなると、割り当てられたノルマを効率良く行うかが評価のポイントになります。つまり、「ソフトウェアの振る舞いを書いているだけ」ということにもなります。

 コンピュータ言語は、あくまでもツール(道具)です。
 kamkamkam3-san が、今後どういった分野の仕事を希望している(興味がある)かが重要だと思います。
 その答えとして、「C言語C++言語アセンブラ言語」を勉強することで実感できると思います。ですので、ぜひ、勉強を続けてください。

 勉強熱心ですね。
 実際に、kamkamkam3-san の言われている、
「なんかプログラムを書いているというより、ソフトウェアの振る舞いを書いているだけだ。。」というのは的を得ています。
 
 経験からなんですが、ソフトウェア会社では、ノウハウとしてライブラリをもっています。ちょうど、Java のクラス・ライブラリーなようなものです。ですから、それらを使って製品を効率良く製品をつくれるかが重要です。実際のソフトウェア・エンジニアは、それをうまく使って効率良くコーディングすることを要求さ...続きを読む

QC言語におけるポインターとconstの関係について

C言語について質問があります。

1.
int **p;
const int **p1 = p; //型に互換性がないという警告

2.
int *p;
const int *p1 = p; //OK

上記2パターンありますが、なぜ1のパターンだと警告がでて、2のパターンだと警告が出ないのでしょうか?
コンパイラはgccの4系列と3系列で試してみましたが同じ結果になりました。
constで修飾されていても、変数の内容を変更できるかできないかだけで、型情報には影響を与えないと考えておりましたが、実際に警告がでてしまい、疑問に思っております

どなたか分かる人がいましたら教えていただけないでしょうか?

Aベストアンサー

JIS X3010の6.3.2.3 ポインタには、次のように記述されています。

「任意の型修飾子qに対して非q修飾型へのポインタは, その型のq修飾版へのポインタに型変換してもよい。」

また、次のようにも記述されています。

「オブジェクト型又は不完全型へのポインタは, 他のオブジェクト型又は不完全型へのポインタに型変換できる。」

何か微妙な記述ですが、型T*から型q T*へは変換できるが、型q T*から型T*への変換は明言を避けています。ただし、後者の記述によって、関数型以外へのポインタ同士の相互変換はできるとなっていますから、型q T*から型T*への変換できないわけではありません。
また、前者の記述は、あくまでも型T*から型q T*への変換のことであって、型T**から型q T**への変換のことではありません。型T**は、(T*)*というイメージですし、型q T**なら(q T*)*というイメージだからです。

型q T*から型T*への変換にせよ、型T**から型q T**への変換にせよ、後者の記述にある「オブジェクト型又は不完全型へのポインタ」ですから、相互変換は可能です。その辺の微妙なところを指摘するために警告が出ているものと思われます。
警告というのは、規格が定めるものではなく、処理系が勝手に出しているものですから、その真意を知るには、処理系の設計者に聞くしかないと思いますが、まあ、この解釈で当たらずとも遠からずかと思います。

ちなみに、C++の場合には#3の回答の通りの理由で、変換することができません(警告ではなく、コンパイルエラーになります)。

JIS X3010の6.3.2.3 ポインタには、次のように記述されています。

「任意の型修飾子qに対して非q修飾型へのポインタは, その型のq修飾版へのポインタに型変換してもよい。」

また、次のようにも記述されています。

「オブジェクト型又は不完全型へのポインタは, 他のオブジェクト型又は不完全型へのポインタに型変換できる。」

何か微妙な記述ですが、型T*から型q T*へは変換できるが、型q T*から型T*への変換は明言を避けています。ただし、後者の記述によって、関数型以外へのポインタ同士の相互変...続きを読む

QC言語でポインターで詰まっています。

下記は、文字化けします。
多分にポインターの定義で不味いのかなと思いますが。
指摘を願います。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *in="abc";
char *out;
while(*out++ = *in++);
printf("%s\n",out);
return 1;
}

Aベストアンサー

No5です。
>char *out=outbufの所を、out=outbuf
>にすると言うのは、具体的にどこが
>どう違うのでしょうか。

これは、
char *out = outbuf;・・・・①

char out = outbuf;・・・・②
としたと理解しました。
①は、 char *out なので、outはchar へのポインターです。
②は、char out なので、outはchar型の1バイトのデータです。

①は
char *data;
data = outbuf;
とおなじです。

②は
char data;
data = outbuf;・・・③
ここで、③はchar型のデータにポインター型のデータを格納しようとしているのでエラーになります。

ほかのエラーも同様にdataがchar型であることに起因したエラーです。

QC言語のポインターで詰まっている

下記が動かない。多分に、ポインターがおかしいと思うが。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out=work;
char *in=buf;

in=strstr(in,"<");
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
printf("%c",p);

//while(strcmp((*out++=*in++),">") != 0);
*out='\0';
printf("%s\n",out);
return 0;
}
01.c: In function 'main':
01.c:14:2: warning: passing argument 1 of 'strcmp' makes pointer from integer without a cast [enabled by default]
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
^
In file included from 01.c:3:0:
c:\mingw\include\string.h:43:37: note: expected 'const char *' but argument is of type 'char'
_CRTIMP int __cdecl __MINGW_NOTHROW strcmp (const char*, const char*) __MINGW_ATTRIB_PURE;

済みません。指摘をお願いします。

下記が動かない。多分に、ポインターがおかしいと思うが。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
char *buf="<title>sample</title>";
char work[256];
char p;

char *out=work;
char *in=buf;

in=strstr(in,"<");
while(strcmp((p=(*out++ = *in++)),"sample") != 0);
printf("%c",p);

//while(strcmp((*out++=*in++),">") != 0);
*out='\0';
printf("%s\n",out);
return 0;
}
01.c: In function 'main':
01.c:14:2: warning: pass...続きを読む

Aベストアンサー

No.3です。
No.4の方へのお礼を拝見しました。

まず、strcmp()というのは、第1引数のポインタから始まる文字列と第2引数のポインタから始まる文字列とを比較し、一致する場合には0を、そうでない場合には0以外を返す関数です。ちなみに、文字列は最後の'\0'までをすべて比較しますので、これでは永遠に一致しません。この場合、strncmp()という、文字数を制限した比較関数を使います。
例:if (strncmp(start, "title", 5) == 0) { ...

>それならば、ポインターに型変換をする事は出来ないのでしょうか。

Cでは他のスクリプト言語と比べ、変数の表記、とりわけポインタが絡んだ場合にちょっと違う記法になります。

宣言の時:
char *a;

ポインタ(アドレス)として利用する場合:
strncmp(a, "title", 5);

ポインタで示される値を参照する場合:
printf("%c", *a);
→printf("%c", a[0]);と同じ動きになる

質問者様はおそらくこのあたりを混乱されているのだと思います。

>while(strcmp((p=(*out++ = *in++)),"title") != 0);

雰囲気的には、1行でこれを表現しようとしているのでしょうが、こういうことをするぐらいなら普通にブロックで書いた方が分かりやすいです。
while (strncmp(in, "title", 5) != 0) {
*out ++ = *in ++;
}
CはPerlと違い、行数が計算コストになるわけではありません。コンパイラが良しなに最適化してくれます。

さらにちなみにですが、大文字小文字を区別しない場合は、strncasecmp()という関数もあります。必要に応じて活用されればよいと思います。

これでお望みの回答になるのではないでしょうか?

No.3です。
No.4の方へのお礼を拝見しました。

まず、strcmp()というのは、第1引数のポインタから始まる文字列と第2引数のポインタから始まる文字列とを比較し、一致する場合には0を、そうでない場合には0以外を返す関数です。ちなみに、文字列は最後の'\0'までをすべて比較しますので、これでは永遠に一致しません。この場合、strncmp()という、文字数を制限した比較関数を使います。
例:if (strncmp(start, "title", 5) == 0) { ...

>それならば、ポインターに型変換をする事は出来ないのでしょうか。

Cでは...続きを読む


人気Q&Aランキング

おすすめ情報