ginga_canvas
ログインはこちらから
ID (ユーザ名)
PW (パスワード)

C
1   a-fukuda   2006-06-23 11:57:03
C, Pro-C, C++等々は、こちらまで♪
2   hime1969   2006-06-23 13:48:36
C, Pro-C, C++てなに?
3   riverchild   2006-06-23 14:00:17
なに?
4   isbn   2006-06-23 21:31:53
英語、イギリス語、香港英語、
みたいなもんかなあー
5   saruhead   2006-06-23 23:38:48
お〜意味深ですが僕にはわからなーい
6   シンゼンタイシ   2006-06-25 08:45:07
ポインタがなかなか上手く扱えなくて困ってます。

理解するために、「こうするといい」とか、「こう考えると分かりやすい」っていう、アドバイスとかありませんか?
7   RIN   2006-06-25 10:36:25
まずは、『中身の値のみ』を見ているか『アドレスから見たの中身の値』を見ているか、の違いを理解することでしょうか。

たとえば、

int i;
int w;
int *p;

w = i;
p = &i;

としたときに、「w」に入れているのは「i」にはいっていた『中身のみ』なので「w」を変更しても「i」の中身は変わりません。

それに対して、「p」の中には「i」の『アドレス』が格納されているため、「*p」に値を入れると『「i」の中身も実際に変わります』。

これが、基本の考え方になるとは思いますが、
あとは、ポインタ練習用のプログラムを実際組んでみて順をおって理解していくのがよいと思います。『百聞は一見に如かず』です。
あと、応用についてはリクエストがあればまた別途書こうと思うので、
聞いてみてください。
8   a-fukuda   2006-06-25 11:34:52
> ポインタがなかなか上手く扱えなくて困ってます。

多くの人がCで引っ掛かるポイントですよね^^;

# 特に、ダブルポインタになった日には・・・自分の場合、頭がウニになりましたorz

基本的な概念については、既にRIN様の方で書かれているので
私からは、自分が参考になった書籍なんぞを紹介したいと思います。

タイトル:Mastering C Pointers
著 者 :Robert J.Traister
訳 者 :新井利幸
発行所 :HBJ出版局
ISBNコード:4-8337-8706-7

当時(私が、20歳くらいの頃だが^^;)、同じようにポインタで
はまっていた時に、自分的には役に立った書籍です。
初版が、1991年1月と古いのですが、基本を抑える内容なので
古さはあまり関係ないと思います。

以上 ご参考になりましたら幸いです。
9   isbn   2006-06-25 20:52:30
私がポインタどところか
「Cの全てがわかった」
と感じた瞬間のお話です。

struct _a {
int b;
char c[10];
...
} *stp;

stp++; /* この文で、コンピュータに何が起こっているのか */
/* わかった瞬間Cのすべてが解決しました */
10   isbn   2006-06-26 09:45:23
「整然と区画された田んぼで、
沢山の釣り人が投げ釣りをしている。」

何を言ってんだろう???の人がほとんどと思いますが、
>あきら@SSさん
いかがでしょうか?
このイメージは。
11   isbn   2006-06-26 10:06:52
二重ポインタを使用したプログラムを1本作ると、
もうこわくなりなります。
【課題】以下の関数を作れ
typedef struct _point { int x, int y } POINT;
int sqrpoints(POINT **ppp, int n);
/* 機能:2次関数y=x*x(二乗書けない)の整数座標を、
    (0, 0)からn個計算して設定し、返す。
 引数:POINT **ppp (in/out) POINT構造体ポインタのアドレス
              POINTをn個確保し、そのアドレスを設定
    int n (in) 求める座標個数
 戻値:0 : 正常 -1 : メモリ確保失敗
*/
12   riverchild   2006-06-26 13:26:35
頭がウニです・・・。
13   saruhead   2006-06-26 16:18:39
↑Cの研修生でポインタのポインタがわからないという人がいたので今見せて見ました〜
さてどうなるかな!
14   シンゼンタイシ   2006-06-26 20:38:08
皆さん分かりやすいご説明ありがとうざいます。
やはり、自分で組んでみて慣れるのが一番ですね。

>>11
**pppは*pppのアドレスを参照している。で、いいんですか?
15   isbn   2006-06-26 22:41:49
>14
その通りです。呼び出し側は、
main() {
  POINT *pp;
  int rc;
  rc = sqrpoints(&pp, 10);
}
とかになります。
16   a-fukuda   2006-06-26 23:15:44
ポインタの概念は、図解すると理解しやすいかと思います。

ポインタ=箱のアドレス
値=箱の中身

> 「整然と区画された田んぼで、
> 沢山の釣り人が投げ釣りをしている。」

> 何を言ってんだろう???の人がほとんどと思いますが、
>>あきら@SSさん
> いかがでしょうか?
> このイメージは。

何となく分かるような分からないような・・・^^; 汗
私のようなヘタレPGには、難しいっす・・・orz 自爆
17   isbn   2006-06-27 10:01:14
>16
「糸を巻いたり緩めたりして、
アドレス加算減算を行なう」っとかって、
フォローを期待していたんですが。
18   saruhead   2006-06-27 12:31:34
研修生に見せたらまだわかりませんとの事orz
指導してあげてくださーい!
19   hime1969   2006-06-27 15:13:06
いまだに????
20   isbn   2006-06-27 22:10:00
>18
明日本社へ行きます。
21   a-fukuda   2006-06-28 12:12:14
> 20

> 明日本社へ行きます。
研修生を、みっちりとしごいてやって下さい w
22   isbn   2006-06-30 12:32:17
本社講義は今日になってしまいましたが、
時間オーバーのなかなか意義深いものにできたようです。
9〜11については納得してくれていました。

ついでに講義で取り上げた内容をひとつ。

printf("%d\n", 3["abcde"]);

とは何か?
23   シンゼンタイシ   2006-07-01 11:49:04
なんですか、それ…?
コンパイルしたら100と出力されました…
24   isbn   2006-07-01 14:24:35
>23さん
やってくれましたか?

Cには配列というものはもともとなく、ユーザインターフェース
と言う意味で用意されているだけなのです。

char a[10];
strcpy(a, "abcde");
printf("%d\n", a[3]);

a[3] を、Cは *(a + 3) と読み替えてコンパイルします。
加算は左右入換えても同じなので、*(3 + a)とも書ける?
このへんでやめときましょう。

Cでは、ポインタがすべてです。
でも、こんな書き方は仕事ではしないでくださいね。

25   シンゼンタイシ   2006-07-01 23:46:37
つまりは…
ポインタで表記しているのと代わりがないというわけですか?
26   isbn   2006-07-02 13:45:25
繰り返しになってしまいますが、
Cは配列表現はポインタ表現に直してコンパイルしています。
だから、*(a + 3)というのはコンパイラの手間を省いてあげている
と言えるでしょうか。

つまり、おっしゃる通り「変わりがない」ということです。
27   Kunugi   2006-07-06 15:04:04
ちなみにCでよく使う手法として以下のような手法があります。

私の場合、プリンタのエミュレーションカード開発で以下のような手法を使いました。

コマンドによって処理を振り分ける場合などに、構造体へコマンドと関数ポインタを追加していけば良いだけなのでPG本体に手を加えることなく、非常に便利な手法です。

typedef struct
{
char cmd[10];
void (*func)(void);
}
ComTBL;

ComTBL TblList[] =
{
{"write", Onara},
{"exit", Noguso},
{"loop", He},
{" ",Nop},
{"",Null}
};


//-----------------------------------------
//
// 構造体に登録してある関数を記述
//
//-----------------------------------------


void main(int argc, char *argv[])
{
ComTBL *test ;

test=TblList ;

if (argc cmd, "") !=0)
{
if (strcmp(test->cmd,argv[1])==0)
{
test->func(); // ここで構造体に登録された関数が呼び出される
}
test++;
}
}
}
28   Kunugi   2006-07-06 15:05:02
あ、ソースコード書きましたがインデント無視されてますね...読みづらくてごめんなさい。
29   isbn   2006-07-04 10:43:37
関数ポインタ配列カッコい〜い。
私のTill-C言語でも、DBアクセスは関数ポインタを追加して
アドインする形にしています。

※Till-C Htmlライクな動的Webページ作成言語
1998 (C) GingaSoftware Inc.
30   isbn   2006-07-18 10:18:07
私がよく使うテクニックに、社内で「オフセット」と呼ばれているものがあります。こんな感じですが、ご存知の方いらっしゃいますか?
例えば、typedef struct DENBUN が定義されていて、
そのメンバに順繰りにアクセスする場合、

struct _offset {
  int ofs;
  int size;
} inf[] = { /* DENBUN構造体オフセット情報 */
  { ((DENBUN *)0)->head, sizeof(((DENBUN *)0)->head) },
  { ((DENBUN *)0)->type, sizeof(((DENBUN *)0)->type) },
  { ((DENBUN *)0)->data, sizeof(((DENBUN *)0)->data) },
  ...
  { -1, 0 }
};

やたらカッコ()が多くて恐縮ですが、このinfを使うと、
多くの文字列メンバが並ぶ構造体のデータ移送や構造体変換に
威力を発揮することがあります。

31   r-ogushi   2006-10-17 23:14:20
Till-C言語って初めて聞いたんですけど、普通のC言語と何処が違うんですか?
32   saruhaed   2006-10-17 23:19:15
ACSI-Cとは、別物?
33   isbn   2006-10-20 09:42:25
>31,32
「Till-C」は、29※で書いた通り、C言語とは全く関係がなく、
私が国立○○○館プロジェクトで開発した、
Copyright銀河の全く新しい(もう古い?)言語です。
JSPやstrutsを相当先取りした、ちょっとした優れものと自負しています。
コンパイラと言語命名は、ゼロエックス(旧クラスタソフトウェア)の
小野寺専務です。
詳しく知りたい方は私までメッセージを!
今はPW言語に賭けていますが、Till-Cもいつか日の目を見たいものです。
34   r-ogushi   2006-10-20 13:14:06
なるほど・・・
ちょっとソースを見てみたいですね!
35   pootaroxgs   2007-06-21 17:08:54
質問があります。
「割り込みやスレッドで共有する変数はvolatileにするべき」
らしいのですが、意味がわかりません。
どなたかご教授願えますでしょうか?
36   isbn   2007-06-21 18:01:30
>35
ある変数が初期化以外に変更がない場合、
その変数をwhile(条件)にすると、永久ループか空抜けどちらかですね。
要するに1回だけ判断すりゃいいので、優れた(大抵の)コンパイラは、
そのように効率最適化したコードを生成します。

これがマルチとなると、自分の知らない所でいつの間にか
その変数の値が変更されるかも知れません。
そこだけ見ると馬鹿馬鹿しいが、それでも毎回律儀にチェックしろ
というのがvolatile修飾子です。
これをしないと、
「あれっ、このタイミングで別スレッドが値を変えているのに、
 ループ脱出しない!なぜだ?」
のような現象が発生する可能性があります。

マルチスレッドは、この他getenv()使用禁止(マルチ用が別にある)など、
想定外の事態が結構あります。
37   r-ogushi   2007-06-21 23:20:09
>36
それは知らなかった。

ここ半年Cをさわっていません。
Cにこだわっているわけじゃないけど、忘れないようにしなしと・・・
38   pootaroxgs   2007-06-22 09:59:00
>36
ありがとうございます。
要するに・・・。
スレッドで動作する中で使われるグローバルな変数なんかはvolatileで宣言するということですかね?
変数変更時にロックとかで排他にしてるっぽいのですが、あんまり関係ないでしょうか?
(うーよくわからん・・・・。volatileは「ボラタイル」?そもそもソースが難しすぎるんです!)
39   isbn   2007-06-26 09:32:02
>38
その通りだと思います。
volatileは、registerとペアで語られることがあるのでしょうか。
ともに、邪魔にはなりませんので、
複数スレッドで使用する変数にはつけておいて間違いないと思います。
40   pootaroxgs   2007-08-17 17:10:28
基本的な質問。
Cでの文字列のおはなし。
自動変数の場合、関数を抜けたときにその領域は保証されなくなりますが、リテラル文字列の場合はなくなることはないんですかね?
引数 char **errm に
*errm = "malloc error.";
とかした場合なんですが。
41   isbn   2007-08-20 22:43:42
>40
リテラル実装の詳細は、さすがにコンパイラ作成者にでも
聞かないとわかりませんが、
基本的にはstaticなものですので、成立します。
同一のリテラルが2ヶ所以上で使われていると、共用されるようです。
お試しください。
42   pootaroxgs   2007-08-21 12:22:47
ありがとうございます。
さすがの明快な回答で助かります。
43   pootaroxgs   2007-08-27 14:58:09
お疲れ様です。
質問です。
#define XXX
とかなっている状態でコンパイルし、ライブラリを作成するのですが、この作成されたライブラリをみて、XXX がdefineされているかどうか、ということを確認する術はあるのでしょうか?

#ifdef XXX
となっているところを通るかどうかの試験で、defineされているかどうかをエビデンスに残すにはどうしたもんか、ということなんですが。
44   isbn   2007-08-28 21:24:02
>43
これは聞いたことがありません...
ライブラリ(.aとします)に関しては、
ar -tでオブジェクトを見る以外のことがあるのかどうか?
提案になりますが、システム全体の共通課題となっているのでしたら、
ライブラリ各ソースファイルに
#ifdef XXX
void XXX_ファイル名(void){}
#endif
を必ず入れる規約とすれば、ar -tの結果をエビデンスに
できるとは思います。
45   pootaroxgs   2007-09-07 14:41:39
お疲れ様です。
「ar -tでオブジェクトを見る」
すらよくわからないのですが、結局のところ、コンパイルに使用したヘッダファイルのdefineしている部分を表示してごまかしておきました。
時間がなさすぎて「なんでもいいからやりとげる」のが第一目標らしいので。。。
オブジェクトを見る、については今度詳しく教えてください。
46   isbn   2007-09-07 19:51:48
システム標準関数ライブラリの内容を表示させた結果です。
[root@/usr/lib/ $] ar -t libc.a | head
init-first.o
libc-start.o
sysdep.o
version.o
check_fds.o
libc-tls.o
elf-init.o
dso_handle.o
errno.o
errno-loc.o

実際やってみてわかったのですが、これでは
#define有無のエビデンスにはなり得ないですね。
大変失礼しました。代わりに、

[root@/usr/lib/ $] nm -s libc.a (ものすごい出力、実行はしないで)

ならば、各オブジェクトファイル内の
関数(あるいは大域変数も)オブジェクト名の
一覧が得られるようです。

次の機会に、直接話をしましょう。
47   gon10   2008-11-14 10:14:22
>30
大変興味深いです。
仕事で活かしたと考えておりますが、DENBUN構造体は
どのような定義なのでしょうか?
恐れ入りますが簡単でいいのでサンプルソースが
見てみたいです。

Copyright 2010 Planet Co.,Ltd.. All rights reserved. No reproduction or republication without written permission.