掲示板

掲示板を置いてみました。ご自由に書き込んで下さい。
ただし、私は根性なしなので、閑古鳥が鳴いたり、荒れてきたと
思ったらとっとと閉鎖する可能性があります。


より新しい記事へ ← 500 件の投稿中 300件目〜251件目を表示 → より前の記事へ
表示件数: 件/頁 


300 Re^7: ポインタと配列について コメント数:  1件
  のぐー   | BXM06466@nifty.ne.jp 2002/02/23 (土) 02:38
 http://homepage1.nifty.com/nogue/
> ANSI-Cの元の章番号の振り方とJISの振り方は異なります。
> ISOの振り方とJISの振り方は同じです。

「元の」と書いてあるのでこの文章は正しいと思いますが、
ISOの規格が決まった時点でANSIもISOに合わせたことをちゃんと書いておかないと誤解をまねくと思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


299 Re^7: ポインタと配列について コメント数:  0件
  かずま   | sakamoto@mc.catv.ne.jp 2002/02/22 (金) 21:49
> >ANSI-Cの章番号の振り方とJISの振り方は同じでしょうか?

JIS            ANSI
(なし)          1. Introduction
(なし)          1.1 Purpose
1. 適用範囲        1.2 Scope
2. 引用規格        1.3 References
(なし)          1.4 Organization of the Document
(なし)          1.5 Base Documents
3. 用語の定義及び規約   1.6 Definitions of Terms
4. 規格合致性       1.7 Compliance
(なし)          1.8 Future Directions
5. 環境          2. Environment
6. 言語          3. Language
7. ライブラリ       4. Library
附属書A 参考文献
附属書B 言語の構文の要約  A. Language Syntax Summary
附属書C 副作用完了点    B. Sequence Points
附属書D ライブラリの要約  C. Library Summary
附属書E 処理系限界     D. Implementation Limits
附属書F 共通の警告     E. Common Warnings
附属書G 可搬性       F. Portability Issues
(なし)          Index
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


298 Re^6: ポインタと配列について コメント数:  3件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/22 (金) 20:49
 http://member.nifty.ne.jp/maebashi/
>ANSI-Cの章番号の振り方とJISの振り方は同じでしょうか?

ANSI-Cの元の章番号の振り方とJISの振り方は異なります。
ISOの振り方とJISの振り方は同じです。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


297 Re^5: ポインタと配列について コメント数:  4件
  TDa   | tda@plum.to 2002/02/21 (木) 23:50
> 変換されたポインタは、配列aの先頭要素を指しています。
> ポインタは、オブジェクトを指します。
> ポインタの値は、オブジェクトのアドレスです。
> ポインタがオブジェクト(配列の先頭要素)のアドレスを指すという表現は不適切です。

間違いの指摘ありがとうございます。この最後の部分の説明は納得できました。

規格書を手元に置いておきたいのですが値段を調べると8400となるとちょっとためらいます。ANSI-Cの章番号の振り方とJISの振り方は同じでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


296 Re^4: ポインタと配列について コメント数:  5件
  かずま   | sakamoto@mc.catv.ne.jp 2002/02/21 (木) 22:39
> Cには配列型もint[3]型もありません。

JIS X 3010 の「6.1.2.5 型」に
 ・配列型(array type)は、要素型(element type)と呼ぶ特定のメンバオブジェ
  クト型をもつ空でないオブジェクトの集合を連続して割り付けることを表す。
とあります。また、次のプログラムはコンパイルでき、実行できます。
 int n = sizeof(int [3]);
 printf("%d\n", n);
int [3] は正しい型名です。(規格書「6.5.5 型名」参照)

> それにprintf("%p", a);というコードとその実行結果を見ればどうしたってaは
> 配列aの先頭の要素のアドレスを指していることには疑いの余地はないと思います。

a は &演算子のオペランドですか。違いますね。
a は sizeof演算子のオペランドですか。違いますね。
だから、a は、配列の先頭要素へのポインタ(左辺値ではない値)に変換されます。
変換されたポインタは、配列aの先頭要素を指しています。
ポインタは、オブジェクトを指します。
ポインタの値は、オブジェクトのアドレスです。
ポインタがオブジェクト(配列の先頭要素)のアドレスを指すという表現は不適切です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


295 Re^2: ポインタと配列について コメント数:  0件
  go 2002/02/21 (木) 11:48
素のアドレスが入っています。ですから
>
> 「配列名aは配列aの先頭の要素を指している」
>
> といって何の差し支えもないと思います。
> }


ありがとうございます!
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


294 Re^3: ポインタと配列について コメント数:  6件
  TDa   | tda@plum.to 2002/02/21 (木) 10:34
> > 「C言語ポインタ完全制覇」
> 僕もこの本は読んでます。ただ、あっちこっち話がとんでるので
> 一貫性があまりみられないように感じます。

まぁ完全に文法を網羅することを目的に書いているわけじゃないですからね。
でも読んでいて面白いと思うんですけど。

> で、他の掲示板で、おなじようなことをうかがったところ、
> 次のようなレスがありました。
>
> オブジェクトとして宣言された識別子は、宣言されたとおりの型を持ちます。
> aはint a[3];と宣言されているので、型int[3](要素数3の配列型)をもちます。
> aはポインタではなく配列なのだからどこも指しません。

少なくともこの文章はおかしいです。
int a[3];
は「aはintの配列(要素数3)」という風にしか読めません。Cには配列型もint[3]型もありません。ポインタ完全制覇にもこういう宣言の読み下し方が書いてあります。HOMEへかえって読めばはじめの方にあります。K&Rの148Pあたりも同じようなことが説明されています。

それにprintf("%p", a);というコードとその実行結果を見ればどうしたってaは配列aの先頭の要素のアドレスを指していることには疑いの余地はないと思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


293 Re: ポインタと配列について コメント数:  1件
  TDa   | tda@plum.to 2002/02/21 (木) 09:20
> int a[3]のとき、
>
> 配列名aは、式の中ではポインタと「みなされる。」
>
> ここで、質問したいのは、
>
> 配列名は、先頭要素を「指している」
> のか?ってことなんです。

なんだかよく読んでみると論点がぼやけている気がしてきたので当初のご質問を考えてみました。
goさんがご自分でおっしゃっているように「式の中では」配列名aは配列の先頭の要素のアドレスが入っています。ですから

「配列名aは配列aの先頭の要素を指している」

といって何の差し支えもないと思います。

#include <stdio.h>
int main(void)
{
int a[] = {10, 20, 30};
int i;

for (i = 0; i < 3; i++) {
printf("a[%d]...%d", i, a[i]);
printf(" : a[%d]のアドレス...%p", i, &a[i]);
printf(" : a...%p", a);
putchar('\n');
}
return 0;
}
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


292 Re: つづき コメント数:  0件
  TDa   | tda@plum.to 2002/02/21 (木) 01:19
> 2. 変換によって生成されるポインタは(変換前の)配列の先頭要素を指す。

私は次のように考えて上記のことについて納得しました。

a[i]は*(a+i)の構文糖である。このことはいいですね。これから出発すると

a[0] <=> *(a + 0) <=> *a
従って a[0] <=> *a
つまり &(a[0]) <=> a
aは配列a[i]の先頭(a[0])をさすポインタです。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


291 つづき コメント数:  1件
  go 2002/02/20 (水) 15:54
次に、配列に対しては次のようなルールがあります。

------------------------- JIS X3010 6.2.2.1 --------------------------
左辺値がsizeof演算子のオペランド、単項&演算子のオペランド、文字配列
を初期化するのに使われる単純文字列リテラルまたはwchar_tに適合する要
素型を持つ配列を初期化するのに使われるワイド文字列リテラルである場合
を除いて、型"〜型の配列"をもつ左辺値は、型"〜型へのポインタ"を持つ式
に型変換する。それは配列オブジェクトの先頭の要素を指し、左辺値ではな
い。
----------------------------------------------------------------------

このルールの適用を受けてaは(sizeofや&のオペランドでなければ)のポイン
タ(右辺値)に型変換されます。よって

1. 変換前の配列aはどこも指さない。
2. 変換によって生成されるポインタは(変換前の)配列の先頭要素を指す。

柴田望洋さんの「C言語問答ポインタ編」
にも同様のことがかかれてます。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


290 Re^2: ポインタと配列について コメント数:  7件
  go 2002/02/20 (水) 15:53

> 「C言語ポインタ完全制覇」

僕もこの本は読んでます。ただ、あっちこっち話がとんでるので
一貫性があまりみられないように感じます。

で、他の掲示板で、おなじようなことをうかがったところ、
次のようなレスがありました。

オブジェクトとして宣言された識別子は、宣言されたとおりの型を持ちます。
aはint a[3];と宣言されているので、型int[3](要素数3の配列型)をもちます。
aはポインタではなく配列なのだからどこも指しません。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


289 Re: ポインタと配列について コメント数:  8件
  かずま   | sakamoto@mc.catv.ne.jp 2002/02/19 (火) 21:29
> 配列の先頭要素のアドレスは
> 固定された値、すなわち「定数」であり、

次のプログラムを実行すると、a が定数でないのがわかるでしょう。

void f() { int a[3]; printf("a = %p\n", a); }
void g() { int b[3]; f(); }
int main() { f(); g(); return 0; }

> 定数にアドレスを代入することはできない。

値にアドレスを代入することはできない。

> それに対し、ポインタは「変数」である。

*(a+2) を考えてみてください。(a+2) は *演算子のオペランドです
から、はポインタです。でも、これは変数ではありません。

「C言語ポインタ完全制覇」にもあるように、ポインタは「型」であり、
「ポインタ型の変数」もあれば、「ポインタ型の値」もあるわけです。
式の中で、配列は「ポインタ型の値」になると理解してください。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


288 ポインタと配列について コメント数:  11件
  go 2002/02/19 (火) 20:32
int a[3]のとき、

配列名aは、式の中ではポインタと「みなされる。」

ここで、質問したいのは、

配列名は、先頭要素を「指している」
のか?


ってことなんです。



いま、僕がわかってる内容を以下に示します。



int a[3];

a[0]=10;
a[1]=20;
a[2]=30;
printf("%d\n",*a); 10が表示される
printf("%d\n",*(a+1)); 20が表示される
printf("%d\n",*(a+2)); 30が表示される


*aってのは、ポインタaが指している先の変数を
表す。

ってことから、aはポインタと解釈されていることがわかる。

ただ、aは「ポインタと解釈されている」のであって、
ポインタではない。

というのも、

配列の先頭要素のアドレスは
固定された値、すなわち「定数」であり、
定数にアドレスを代入することはできない。
それに対し、ポインタは「変数」である。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


287 Re: 体当たり学習 List5-17 コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/17 (日) 03:34
 http://member.nifty.ne.jp/maebashi/
>早速ですが「体当たり学習」List-1-17 realloc.cの
>input_string関数中のgetc()についてです。

11行目の

p.275 のList5-7ですね。

このミスは、正誤表に載っていたのですが、

>それからこのinput_stringですが文字列入力時に
>いきなりリターンすると*pがNULLの状態でナル文字を
>代入することになります。

こちらの問題の方が重要なので、正誤表の該当項目を
差し替えました。

「いきなりリターン」以前に、末尾のナル文字の分の
領域を確保していませんでした。もうしわけありません。

>while ((ch = getc()) != '\n') の書き方をあきらめて
>fget,sscanfで処理するのが正攻法なのでしょうか?

「1文字ごとにrealloc()」してよいのであれば、今回
正誤表に載せたリストで動作するはずです。

ご指摘ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


286 体当たり学習 List5-17 コメント数:  1件
  TDa   | tda@plum.to 2002/02/16 (土) 22:04
早速ですが「体当たり学習」List-1-17 realloc.cのinput_string関数中の
getc()についてです。

11行目の
while ((ch = getc()) != '\n') {
の部分は
while ((ch = getc(fp)) != '\n') {
が正しいのではないかと思い、確認をお願いしたいと思います。

それからこのinput_stringですが文字列入力時にいきなりリターンすると*pがNULLの状態でナル文字を代入することになります。私の環境ですとbcc32だとメモリエラーで落ちました。LSIC86だと"NULL"が返ってきました。
while ((ch = getc()) != '\n') の書き方をあきらめてfget,sscanfで処理するのが正攻法なのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


285 本を読ませていただいています。 コメント数:  0件
  TDa   | tda@plum.to 2002/02/16 (土) 21:43
こんにちは、前橋さんの標準プログラマーズライブラリシリーズの3冊を読ませていただいております。10年前の学生時代に教養課程で単位をとって以来結局それ以上深めることなくきました。おきまりのようにポインタ、構造体、共用体あたりで挫折しておりました。

三十路にしてソフトウェアハウスに飛び込みましてそこではVBをさわっているのですがスキルアップをと思い前橋さんの本を手にしています。前橋さんの書き口はあくまでストレートでわかりやすいと思います。

本文中のコードを実際に打ち込んでみて疑問に思うこともでてきておりますので今後もたびたびおじゃますると思いますがご教示いただけるとありがたく思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


284 Re: 関数への配列引数について コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/13 (水) 00:19
 http://member.nifty.ne.jp/maebashi/
>式中で配列はポインタとして評価されるため、
>関数は引数や戻り値に配列を取ることができない。

うーん、由来についてはDennis Ritchieに聞かないと正確なところは
わかりませんが、式中では配列がポインタに読み替えられるという仕様と、
関数が引数に配列を取ることができないという仕様を比べたら、
前者のほうが「先」なんじゃないでしょうか?

もともとBの時代からの「ポインタと整数の区別なし・配列は
ポインタ演算のsyntax sugar」という仕様があって、関数に
配列を渡せないのはそこからくる当然の仕様だったのではないかと。

構造体の値渡しは、K&R初版の頃には存在してませんでしたし。

>配列は要素数が異なると違う型とみなされるため、任意の大きさの
>配列を引数に取るような仮引数の型が存在しない。

この辺が悩みのタネだというのは否定しませんが。初期のPascalでは
配列を引数で渡すとき要素数まで合ってなきゃだめだったそうですし。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


283 関数への配列引数について コメント数:  1件
  xiu   | ogihara@kams.eg.t.kanazawa-u.ac.jp 2002/02/12 (火) 02:58
Cにおいて、
式中で配列はポインタとして評価されるため、関数は引数や戻り値に配列を取ることができない。
という仕様について、K&Rなどではこの理由を「配列のサイズは大きいかもしれないので、これは効率の面からも好ましい」(うろ覚えです)と説明していますが、これはどうも説得力に欠けるように感じられます。これはポインタで渡すメリットであって、ポインタで渡さなければならない理由にはなっていません。
また、この論法だと構造体を値渡しできる理由を説明できません。むしろ
配列は要素数が異なると違う型とみなされるため、任意の大きさの配列を引数に取るような仮引数の型が存在しない。唯一の解決法が先頭要素へのポインタを渡すことである。

というのが本当の理由のような気がします。いかがでしょうか?この解釈に問題があればご指摘ください。

余談ですが、仮引数でポインタに読み替えられる[]は一見、任意の大きさの配列型というふうに見えてしまうんですよね。まぎらわしい。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


282 Re^3: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  0件
  xiu 2002/02/10 (日) 03:09
> 関数呼び出しのとき、mlstr[] の(先頭?)アドレスが、ポインタ char *mlstr に渡されていると考えてもよろしいのでしょうか。

いいと思います。配列とポインタは型としては異なるのですが、式中で配列はポインタに変換されるため、関数へはポインタが渡されます。

おそらく、そのあたりは「ポインタ完全制覇」に詳しいと思います。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


281 Re: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/09 (土) 22:45
 http://member.nifty.ne.jp/maebashi/
用語の話ですが、一応突っ込んでおきます。

> そして、途中経過の打ち出しで,プログラムが文字列リテラルの一部を'\0'で
> 置き換えながら、文字列を切断していく様子なども,一部確認することが出来
> ました。

修正版のプログラムで、「一部を'\0'で置き換え」られているのは
「文字列リテラル」ではありません。

「文字列リテラル」と言うと、ソース中で""で囲まれた文字列を指します。
修正版のプログラムでは、文字列リテラルを別配列にコピーしているので、
コピーの側は「文字列リテラル」ではありません。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


280 Re^4: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/09 (土) 21:18
 http://member.nifty.ne.jp/maebashi/
>int func(void){ return 1;}
>であれば、正常終了時に
>if( func() )
>を、通過できるかな、等と考えてしまいました。

一般に、関数が正常終了/異常終了時にそれぞれ何を返すかは、
「流儀の問題」です。正常時にTRUE(1)、異常時にFALSE(0)という
流儀もよく見ます。

ただ、main()に関しては、正常時には0だと定められています。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


279 Re^3: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/09 (土) 21:16
 http://member.nifty.ne.jp/maebashi/
>*mlstr = '\0';
>printf("mlstr..%s\n", mlstr);
>
>のとき、何も打ち出してくれなかったので、
>この時点で残りの文字列を指し示すポインタが
>無いことになるのではないかと思ったのです。

無くても別に困らないと思うんですが。

この場合でも、

printf("%s\n", mlstr + 1);

とすれば、続きが見えるはずですし。

>のようなプログラムを書いてしまったとき、実行終了後に、
>メモリの中に "de" が消去されずに残ってしまうような
>ことが起こらないのだろうかと思ったのです。

起きません起きません (^^;

C の文字列は単なる「文字型の配列」です。
'\0'で終端するというのは、「約束事」に過ぎません。

main()関数のおしりで、配列 mlstr の内容を、自前でfor文で
回して出力してみてはどうでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


278 Re^3: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  1件
  サカイ   | sakai@jsdi.or.jp 2002/02/09 (土) 09:14
> > http://member.nifty.ne.jp/maebashi/zakki/jiteec.html
>
> 細かい突っ込みですみませんが、main関数の戻り値は0ですね(意図してるのであればいいんですけど)。

雑記帳にありますように、文責は、質問を差し上げた私にあります。

これから題記試験を受けようとしている素人で、常識も知らず申し訳ありません。
ポインタ完全制覇でも、main()の型は、int であり、正常終了は return 0;である
と、記載してありました。
これだから、素人は困るといわれるかもしれませんが、
int func(void){ return 1;}
であれば、正常終了時に
if( func() )
を、通過できるかな、等と考えてしまいました。

だけど、電子回路の世界でも負論理で設計されることも有りそうだし、今後は
return 0; で統一いたします。
ありがとうございました。




【新規投稿】 【この投稿にリプライ】 【投稿者削除】


277 Re^2: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  1件
  サカイ   | sakai@jsdi.or.jp 2002/02/08 (金) 22:03
ご指導ありがとうございます

> char mlstr[] と書いてあっても、「配列型からポインタ型への変換」
> が自動的になされて最後はポインタが使われているのです。

関数呼び出しのとき、mlstr[] の(先頭?)アドレスが、ポインタ char *mlstr に渡されていると考えてもよろしいのでしょうか。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


276 Re^2: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  1件
  サカイ   | sakai@jsdi.or.jp 2002/02/08 (金) 21:29
> printf("mlstr..%p\n", mlstr);
> *mlstr = '\0';
> printf("mlstr..%p\n", mlstr);
>
> とすると、mlstrに変化がないことがわかると思います。
>
> # という話ではない?

説明が下手で申し訳ありません。とんでもない常識はずれなのかもしれませんが、

*mlstr = '\0';
printf("mlstr..%s\n", mlstr);

のとき、何も打ち出してくれなかったので、この時点で残りの文字列を指し示すポインタが無いことになるのではないかと思ったのです。

そして、その延長で、何かの拍子に

void func(char *strf )
{
strf=strf+2;
*strf='\0';
}

int main(void)
{
char str[] = "abcde";
func( str );
return 0;
}

のようなプログラムを書いてしまったとき、実行終了後に、メモリの中に "de" が消去されずに残ってしまうようなことが起こらないのだろうかと思ったのです。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


275 Re: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  2件
  てんま 2002/02/08 (金) 10:00
> ポインタと配列の違いを、本当には理解していないと分かりました。

この例の場合はポインタと配列の違いで動く動かないのではなく
文字列リテラルの書き換えができないから動かないだけです。
文字列リテラルの書き換えを許すコンパイルオプションがあるなら
それを指定すれば動作するようになります(未確認)
gcc なら -fwritable-strings

char mlstr[] と書いてあっても、「配列型からポインタ型への変換」
が自動的になされて最後はポインタが使われているのです。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


274 Re^2: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  2件
  xiu 2002/02/08 (金) 08:28
> http://member.nifty.ne.jp/maebashi/zakki/jiteec.html

細かい突っ込みですみませんが、main関数の戻り値は0ですね(意図してるのであればいいんですけど)。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


273 Re: 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  5件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/08 (金) 03:02
 http://member.nifty.ne.jp/maebashi/
>題記のCプログラム(突然ですが、記事の長さ500文字が気になり、
>申し訳ありません。)

確かにこの掲示板は文字数制限がキツいですが、
ちょうど雑記帳のネタにしたので(^^; Webに上げてしまいました。

http://member.nifty.ne.jp/maebashi/zakki/jiteec.html

で見えます。
# 問題ない... ですよね? > サカイさん

>そこで,ちょっと疑問に思ったのですが
>for( ; *mlstr != '>'; mlstr++)
>;
>*mlstr = '\0';
>を実行すると,この時点では,mlstr+1 以降の文字列を示す変数
>名は、無くなってしまった様に思えて、なんとなく不安なんですが、

*mlstr = '\0'では、mlstrの値は変わってはいません。
mlstrの指す先の文字が書きかえられただけです。

printf("mlstr..%p\n", mlstr);
*mlstr = '\0';
printf("mlstr..%p\n", mlstr);

とすると、mlstrに変化がないことがわかると思います。

# という話ではない?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


272 平成13年秋期基本情報処理技術者試験午後問6について コメント数:  10件
  サカイ   | sakai@jsdi.or.jp 2002/02/07 (木) 22:24
はじめまして。サカイと申します。よろしくお願いします。

題記のCプログラム(突然ですが、記事の長さ500文字が気になり、申し訳
ありません。)を実行するべく、追加したmain()で、データの初期値を
char *mlstr = "hoge";
と定義して旨く行かず、失礼にも本ホームページの個人アドレスにメール差
上げたところ、ご親切に
char mlstr[] = "hoge";
とすれば実行できると教えて頂きました。その通り試した結果、実行できま
した。大変有難うございました。教科書を読んで分かった積りになっていて
も,ポインタと配列の違いを、本当には理解していないと分かりました。

そして、途中経過の打ち出しで,プログラムが文字列リテラルの一部を'\0'で
置き換えながら、文字列を切断していく様子なども,一部確認することが出来
ました。

そこで,ちょっと疑問に思ったのですが
for( ; *mlstr != '>'; mlstr++)
;
*mlstr = '\0';
を実行すると,この時点では,mlstr+1 以降の文字列を示す変数名は、無く
なってしまった様に思えて、なんとなく不安なんですが、そういう解釈は間違
っているのでしょうか。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


271 Re^7: 文字列リテラルへのポインタ演算について コメント数:  0件
  てんま 2002/02/06 (水) 14:52
> C++では文字列リテラルはconst char []になったのですか。
はいそうです。

char* p="abc";
は例外的に「特別の変換」によって今でも許されています。
が deprecated 推奨されないとされています。(4.2-2, Annex D.4)

「特別の変換」が効かない例として (15.1-3)
throw "hoge"; を catch(char*) で受け取ることはできない
というのが挙げられています。
この場合 catch(const char*) にしなさいとのことです。
# 誰かさんはこれに一度はまったらしい...
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


270 Re^6: 文字列リテラルへのポインタ演算について コメント数:  1件
  xiu 2002/02/06 (水) 11:10
C++では文字列リテラルはconst char []になったのですか。
確かにそれならエラーになりますね。

てんまさん、ご丁寧な解説ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


269 Re^5: 文字列リテラルへのポインタ演算について コメント数:  2件
  てんま 2002/02/05 (火) 19:31
長くなったので続きを別発言とします。

> また、C++で5行目のコードは通りますが、&aと&"abc"の違いは何なのでしょうか?
前者は a が non-const-object だから non-const-object へのポインタ
後者は "abc" が const-object だから const-object へのポインタ
提示の例では a2 は non-const-object へのポインタなので
&a で初期化することは可能であっても &"abc" で初期化するのは誤りです。
配列オブジェクトの初期値とポインタはぜんぜん別物。

全部を const char にするとC++ではコンパイル通るようになります。
でも今度はCでコンパイル通らないはずです。
ちなみに VC++ では const char にしても char にしてもコンパイル通りません。
-Za -Ze で振る舞いが変わるかと思ったけど変化なし。なんだかなぁー。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


268 Re^4: 文字列リテラルへのポインタ演算について コメント数:  3件
  てんま 2002/02/05 (火) 19:29
> 1:int main()
> 2:{
> 3: char a[] = "abc";
> 4: char (*a1)[4] = &"abc";
> 5: char (*a2)[4] = &a;
> 6: return 0;
> 7:}
C++ソースの場合
gcc-2.95.3 では
chartype.cpp:4:warning: initialization to `char (*)[4]' from `const char (*)[4]' discards qualifiers
gcc-3.0.3 では
chartype.cpp:4: cannot convert `const char (*)[4]' to `char (*)[4]' in initialization

Cソースならどちらも無警告でコンパイルにとおりました。

VC++6の警告は信用できません(そもそも ISO/IEC 14882 に準拠してない)

> C++では文字列リテラルに対する&演算子の扱いが変わったのでしょうか?
私が ISO/IEC 14882:1998 を読んで理解している範囲では、変わっていません。
変わったのは文字列リテラルのほうです。

【新規投稿】 【この投稿にリプライ】 【投稿者削除】


267 Re^3: 文字列リテラルへのポインタ演算について コメント数:  4件
  xiu 2002/02/05 (火) 15:24
ご指摘ありがとうございます。これで疑問は氷解したと思ったのですが、
VC++で以下のコードをC,C++形式でそれぞれコンパイルすると、

1:int main()
2:{
3: char a[] = "abc";
4: char (*a1)[4] = &"abc";
5: char (*a2)[4] = &a;
6: return 0;
7:}
Cでは4行目で
warning C4047: 'initializing' : 間接参照のレベルが 'char (*)[4]' と 'char [4]' で異なっています。

C++では4行目で
error C2440: 'initializing' : 'char [4]' から 'char (*)[4]' に変換することはできません。(新しい動作 ; ヘルプを参照)

C++では文字列リテラルに対する&演算子の扱いが変わったのでしょうか?
また、C++で5行目のコードは通りますが、&aと&"abc"の違いは何なのでしょうか?
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


266 Re^2: 文字列リテラルへのポインタ演算について コメント数:  5件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/02/05 (火) 02:02
 http://member.nifty.ne.jp/maebashi/
>VC++,gccで以下の二つのコードがいずれも同じ結果になりました。

えっ? と思って実験してみましたが、

char *a1 = &"abc";    …(a)
char (*a2)[4] = &"abc"; …(b)

gcc(egcs-2.91.57), bcc(Borland C++ 5.5)共に(a)の方に警告を
出しました。(b)の方はOKです。

VC++は今手元にありません。明日試してみます。

# 実行すればきっと同じ結果になると思います。アドレスは同じで
# すから。

gcc:
string.c:5: warning: initialization from incompatible pointer type

bcc32:
警告 W8075 string.c 5: 問題のあるポインタの変換(関数 main )

>よくよく考えたら文字列リテラルは左辺値ではありませんでした。

文字列リテラルの型は「charの配列」ですから、左辺値ですよ。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


265 Re: 文字列リテラルへのポインタ演算について コメント数:  6件
  xiu 2002/02/04 (月) 16:26
追伸:
よくよく考えたら文字列リテラルは左辺値ではありませんでした。
つまりこの式自体、ANSI Cでは許されないですね。

でもなぜコンパイルが通るのか不思議。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


264 文字列リテラルへのポインタ演算について コメント数:  7件
  xiu 2002/02/04 (月) 16:18
VC++,gccで以下の二つのコードがいずれも同じ結果になりました。
このような演算についての規則はK&Rの参照マニュアルでは確認できなかったのですが、これはANSI Cでは両方認められるのでしょうか?
1)
char *p = "012345";

2)
char *p = &"012345";

ちなみに3)として
3)
char a[5];
char *p = &a;

はもちろんエラーになります。3)がだめなら2)もだめだと思うのですが。
不思議です。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


263 Re^2: 1バイトのビット数 コメント数:  0件
  tos 2002/02/01 (金) 09:00
> <limits.h> を #include して、8 の代わりに CHAR_BIT を使いましょう。
ありがとうございます。
まったく気がづきませんでした。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


262 Re: 1バイトのビット数 コメント数:  1件
  kit 2002/01/31 (木) 21:43
<limits.h> を #include して、8 の代わりに CHAR_BIT を使いましょう。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


261 1バイトのビット数 コメント数:  2件
  tos 2002/01/31 (木) 09:13
また、基本的なことどなたか教えてください。
1バイトのビット数は、8ビットでしょうか?

やりたいことは、ビットフィールドを使用せずに、
下記のように、変数にある状態をセットしたいと
思っています。

----------------------
static unsigned int hoge;
static int index;

void set_func(void)
{
hoge |= 1 << index;
index++;
}
----------------------
で、上記の「hoge++」の後に、

if (hoge >= (8 * sizeof(unsigend int) - 1)) {
hoge = 8 * sizeof(unsigend int) - 1;
}

のような文を追加したいのですが、
はて、1バイトは8ビットって決めていいのかなと思ったものですので。


【新規投稿】 【この投稿にリプライ】 【投稿者削除】


260 Re^3: DrawLine() コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/01/27 (日) 16:22
 http://member.nifty.ne.jp/maebashi/
> 遅々と読み進んでいるのですが(^^;、新たに、誤植とおぼしき箇所を
> 発見いたしましたので、御報告差し上げます(大したことないもので
>すいませんが)。

ご指摘ありがとうございます。正誤表に載せておきました。

また正誤表が増殖しつつあります。もうしわけありません。> 読者の皆様
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


259 Re^2: DrawLine() コメント数:  1件
  金山@OpenJE   | majiro@openje.org 2002/01/27 (日) 03:38
 http://www.openje.org/~majiro/
こんにちは、金山@OpenJEです。

> > 2年ほど前、Java互助会で、「Java仮想マシン仕様」を読む会というのが
> > あり、そこでお会いしましたが、覚えていらっしゃいますでしょうか…。
> > #それ一度きりですので、もう忘却の彼方かもしれません…。
>
> 覚えております。あの時は曙橋でしたっけ。

そうですそうです。

遅々と読み進んでいるのですが(^^;、新たに、誤植とおぼしき箇所を発見いたしましたので、御報告差し上げます(大したことないものですいませんが)。

P80のFig.2.4

「P1」は、「p1」ですよね。

「P2」は、「p2」ですよね。

P117のFig.2.22

「Y」は、「y」ですよね。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


258 Re: DrawLine() コメント数:  2件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/01/22 (火) 03:12
 http://member.nifty.ne.jp/maebashi/
> こんにちは、金山@OpenJEと申します。

こんにちは。おひさしぶりです。

> 2年ほど前、Java互助会で、「Java仮想マシン仕様」を読む会というのが
> あり、そこでお会いしましたが、覚えていらっしゃいますでしょうか…。
> #それ一度きりですので、もう忘却の彼方かもしれません…。

覚えております。あの時は曙橋でしたっけ。

> それで、まだ最初の方しか読んでないのですが、誤植とおぼしき
> 箇所について、お知らせ差し上げます。

ご指摘ありがとうございます。

> P34 の Fig. 1.3 の図中で、
> 「DrawLine()などの公開された関数」
> とありますが、
> 「drawLine()などの公開された関数」
> (頭のdが小文字)ですよね。

その通りです。申し訳ありません。
正誤表にいれておきます。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


257 DrawLine() コメント数:  3件
  金山@OpenJE   | majiro@openje.org 2002/01/21 (月) 22:57
 http://www.openje.org/~majiro/
こんにちは、金山@OpenJEと申します。

2年ほど前、Java互助会で、「Java仮想マシン仕様」を読む会というのがあり、そこでお会いしましたが、覚えていらっしゃいますでしょうか…。

#それ一度きりですので、もう忘却の彼方かもしれません…。

さて、前橋さんの「Java 謎+落とし穴徹底解明」を、大変面白く拝読させていただいてます。

それで、まだ最初の方しか読んでないのですが、誤植とおぼしき箇所について、お知らせ差し上げます。

P34 の Fig. 1.3 の図中で、
「DrawLine()などの公開された関数」
とありますが、
「drawLine()などの公開された関数」
(頭のdが小文字)ですよね。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


256 Re: Serializableのところで。 コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/01/20 (日) 20:28
 http://member.nifty.ne.jp/maebashi/
> さて、その中で1点気になる個所がありましたのでここに記します。
> 本書p278 5.3.2「Serializable」の1行目、
> (×)"readObject()を一発呼ぶ"
> (○)"writeObject()を一発呼ぶ"
> なのではないかなと思いました。

すみません、おっしゃる通りです。

正誤表に入れておきました。

ご指摘ありがとうございました。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


255 Serializableのところで。 コメント数:  1件
  M.U   | uchiyama00@mail.goo.ne.jp 2002/01/20 (日) 03:03
はじめまして。
「Java謎+〜」のURLをみてこのページを訪れました。
本の内容につきましては、自分もC(++)プログラマを
やっていることもあってか、大変しっくりくるものがあり、
興味深く読ませて頂きました。

さて、その中で1点気になる個所がありましたのでここに記します。
本書p278 5.3.2「Serializable」の1行目、
(×)"readObject()を一発呼ぶ"
(○)"writeObject()を一発呼ぶ"
なのではないかなと思いました。
もしもご参考になれば幸いです。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


254 Re: 重箱の隅 コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/01/14 (月) 15:01
 http://member.nifty.ne.jp/maebashi/
> とよ と申します。はじめまして。

はじめまして。

> P155 4-6行目
> shapes.length
> shape[i].color
> のどちらかが間違いではないかと思います。
> (前ページの流れからしてshapes[i]でしょうか?)

ご指摘ありがとうございます。正誤表に入れておきます。
もうしわけありません。

> #第2版に間に合うとよいのですが…

残念ながら第2刷は既に刷っています (;_;)
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


253 重箱の隅 コメント数:  1件
  とよ 2002/01/14 (月) 11:43
とよ と申します。はじめまして。

P155 4-6行目
shapes.length
shape[i].color
のどちらかが間違いではないかと思います。
(前ページの流れからしてshapes[i]でしょうか?)

#第2版に間に合うとよいのですが…
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


252 2ちゃんにスレが コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2002/01/11 (金) 03:42
 http://member.nifty.ne.jp/maebashi/
立ちましたな。

「Javaの謎+落とし穴徹底解明」を読まない奴は厨房
http://pc.2ch.net/test/read.cgi/tech/1010575251/

ジサクジエンじゃないってのに。

1:
>グローバルとパブリックは全く違うだろ。

publicであるだけでなく、staticであることも入れて欲しい...

28:
>>Javaにはポインタがない」という言説の "ウソ"が
>今更何をって感じではあるがね。

まあ、そうですね。

# せめて 3年前に出せていればなー。

でも、2chを見ててもまだ「Javaにはポインタがない」って主張は
ちょくちょく聞くように思います。

そういう意味では、本の「スタンス」を決めるにあたって
2chもいろいろ参考にしたと思うので、

10:
>内容はJavaHouseやらで議論されたことをまとめたような感じもある
>でも結構2chからも拾ってそう・・・

拾ったと言えるかもしれません。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】


251 Re: X-Draw コメント数:  0件
  (ぱ)   | PXU00211@nifty.ne.jp 2001/12/27 (木) 01:43
 http://member.nifty.ne.jp/maebashi/
> p.213
> 誤 iimport java.applet.Applet;
> 正 import java.applet.Applet;

正誤表に入れておきます。ご指摘ありがとうございます。

> class XDrawApplet の内部クラス ClearButtonListner など
> には private が付いているのに、
> class XDrawFrame の内部クラス XDrawWindowAdapter には
> private が付かないのはなぜでしょうか?

「続・Java言語入門」からアプレットケーションのテクニックを
パクった時の名残りのような。

> 次の行の canvas には XDrawApplet.this. が付いていませんし、
> 他の 3つの Listner では、shapeCollection もそのまま書かれ
> ていますから。

thisの表記には確かに不統一があります。X-Drawのソースでは
this.をなるべく付けるようにしていますが、他の箇所のソースでは
そうなっていないところがたくさんあります。

特に内部クラスから外側のクラスのメンバを見る時、Hoge.this.piyo
はちょっと長ったらしいような気がしてまして...

これらは特に間違いというわけではないはずですので、いずれ統一
するかもしれませんが、少し時間をください。
【新規投稿】 【この投稿にリプライ】 【投稿者削除】

Copyright(C) 1999 NIFTY Corporation
All Rights Reserved.