C言語のポインタってなんですか?

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
教えてください
2デフォルトの名無しさん:03/06/20 13:20
さあな。
*
単発質問断固反対
5デフォルトの名無しさん:03/06/20 13:23
>>4
コピペ断固反対
6デフォルトの名無しさん:03/06/20 13:24
それにはまずC言語の変数や構造体どういう風に記録されているかから説明しなければならない。
74:03/06/20 13:25
>>5
残念だが、手入力だ。
8デフォルトの名無しさん:03/06/20 13:25
>>4
マルチポスト断固反対
削除依頼完了
>>1
マルチ厨。
やっぱスレ立てやがった。

C言語のポインタってなんですか?
http://pc3.2ch.net/test/read.cgi/pc/1056082601/l50
111:03/06/20 13:36
プログラム板いけつったじゃん
スレ立てろと書いてあったか?
131:03/06/20 13:37
スレたてちゃだめなの?
ちーちゃんのポインタ
>この板はプログラムを作る人のための板です。

>あらゆる質問はまずすれ立てるまでもない質問はここでスレにしてください。
161:03/06/20 13:39
初心者でしりませんでしたすいません
ハァハァ

いいよ、いいよぉ〜
18山崎 渉:03/07/15 10:44

 __∧_∧_
 |(  ^^ )| <寝るぽ(^^)
 |\⌒⌒⌒\
 \ |⌒⌒⌒~|         山崎渉
   ~ ̄ ̄ ̄ ̄
19山崎 渉:03/07/15 14:04

 __∧_∧_
 |(  ^^ )| <寝るぽ(^^)
 |\⌒⌒⌒\
 \ |⌒⌒⌒~|         山崎渉
   ~ ̄ ̄ ̄ ̄
20山崎 渉:03/08/02 02:51
(^^)
21山崎 渉:03/08/15 17:53
    (⌒V⌒)
   │ ^ ^ │<これからも僕を応援して下さいね(^^)。
  ⊂|    |つ
   (_)(_)                      山崎パン
22デフォルトの名無しさん:03/08/16 10:48
タグみたいなもんです
23デフォルトの名無しさん :03/08/16 11:05
ポラロイドカメラの「ポラロイド」ってなんですか?
>>23
21世紀のメイド型ロボットの総称。
25デフォルトの名無しさん:03/08/16 14:24
僕はなんで童貞なんですか?
>>25
仕様です
27デフォルトの名無しさん:03/08/27 11:02
ドッグタグみたいなヤツだな
まず、坂村健の化身・実身モデルを学べ。
ペンの先から赤い光がでて、プレゼンのスクリーンを指すやつ
ポインタとは何かを理解するより、先にポインタで何ができるかを学んだ方がいい。
理論は後からついてくる。
まず最初に覚えるべきポインタの利用方法は、関数の引数への代入。
関数は引数に入力、返値に出力という構造が基本だが、これだと出力は一つしか持てない。
そこで本来入力としての引数にポインタを使えば、引数も出力として扱うことができる。
なぜそうなるのか?という疑問を持ったなら、調べてみるといい。
アドレス渡しと値渡しの違いが分かれば、ポインタの仕組みが理解できてくるだろう。
やつぱし初心者はポインタで悩むんだね。
32デフォルトの名無しさん:03/09/01 23:08
Cカップのボインタンって何ですか?
>>32
メールアドレス教えてお金渡してもらう
34デフォルトの名無しさん:03/09/01 23:27
>>1
それとあと構造体でみんな挫折するそうです。
ポインタのポインタとか、ポインタを返す関数へのポインタとか、
そういうのが出てくると死ねるそうです。
上級者にとって、初心者が何故ポインタが理解できないかを
理解することは有益だろうか?
37デフォルトの名無しさん:03/09/01 23:58
初心者がC言語からはじめるのが間違い
アセンブラから覚えろ
そしたらこんなアホな質問はなくなる
39デフォルトの名無しさん:03/09/02 00:06
初心者が口から牛乳飲むのが間違い
鼻から飲め
そしたらいざというとき口から出せる
LPPPPPPPPPPPPPPCSTR lppppppppppppppString;
>>30
C の関数は全て値渡しに過ぎない。
ポインタ値と言う値を渡すだけ。
ぬるぽいんた
43デフォルトの名無しさん:03/09/20 21:59
こっちへどうぞ。
ttp://pc2.2ch.net/test/read.cgi/tech/1030901827/

終了
>>41
って、本に書いてあったから、真似して言ってみたかったんだろ?
もう一度>>30を読み返せ。っていっても、オマエには理解不能か(w

>>43
終了させたいならあげるなよ。
45supermathmania ◆ViEu89Okng :03/09/23 17:11
Re:>41 確かにポインタ値渡しだが、ポインタ型変数で何が出来るかを踏まえて説明して欲しいものだ。
46デフォルトの名無しさん:03/09/23 17:25
c#とC++と ObjectiveC との切り替えだよ >>1
ちょっと太目の女の子の胸についているのだよ。
ぬるぽ

はポインタですよ。
>>48
だからガッってやられるんですね。
javaはぼいんたん無いですよー。
gj台追いf;亜jんhきgf;あきgふぁhにごれ
ポウィンタ
52デフォルトの名無しさん:03/11/27 17:24
>>50
なんで、Javaにポインタはないんですか?
>>52
ぬーんC言語が糞だからだよ
るるるむしろC言語のポインタが糞だと言ったほうがいい
ぽっぽーつまり要するにC言語のポインタはポインタと自称しているわりに余計な機能が付きすぎてるってこった

だからJava様はそんなヘポインタと一緒にされたくなかったわけなのです
>>52
ポインタはあるんだけどポインタと言いがたい状況だ。
アドレスを参照する具合な感じだからポインタを扱ってる用に見えないだけではないのかな?
ポインタは定義をきちんとやろうとするとドツボに嵌る。
アセンブラから入った人は素直にアドレス型だとわかる。
アセンブラやらない今の人は、ポインタ型=クラスだと
思い込みがちだが、全然違うもの。構造体へのポインタ型
と代入操作に対する扱いにくさは似ていなくも無いが。
>>55
経験が物をいうんじゃないか?
いくべんも失敗して理解しる
ポインタ型ってさー
int型のポインタ型とかchar型のポイント型とかあって
わけわかんねーよ!

アセンブラのほうがよっぽど素直だ
>>57
指し示す先の位置の他に、指し示す先がどんな種類のデータか?と言う情報があるだけじゃん。
>>57
じゃあアセンブラしてください。

int型のポインタ型は変

int型のポインタとは言うがポインタ型っておかしくないか?
ポインタは型では無いのでわけわかめにはなりません
キャスト式に使えるから型は型でしょ。構造体も。
>>60
そういう風に言うならば long型 じゃね?
>>59
>ポインタは型では無いのでわけわかめにはなりません

ポインタ型は存在する訳で(ry
>>62
略してないよ全然w

あぃ、あるんですね。
わかりました
64デフォルトの名無しさん:03/11/28 15:37
char **p;
int a,b,c,…;

*(p+0) = &a;
*(p+1) = &b;
*(p+2) = &c;


これ、領域も確保してなくとも*(p+n)には代入していけるのですか?
できません
6665:03/11/28 16:59
□を変数を格納する箱だと思ってください

面倒くさいので全部 int で逝きます

   a
   □   int型 a です

  *p    a
   □─→□

int型をさすポインタも変数であるわけね

  **pp   *p    a
   □─→□─→□

**になると int型をさすポインタをさすポインタ になります。

で、>>64だと *p が何処にあるか指定されて無いから代入できないわけ
代入できても暴走する可能性がある
>>64
どこか有効な領域を指していれば出来る。

# 意図したものとは恐ろしく違うだろうがな。(w
>>67
出来るかも知れないけどさぁ・・・やばくないかなぁ〜^^;
6964:03/11/28 18:01
int **p;

p = (int **)malloc(sizeof(int *))
p = &a[0];

p+1 = (int **)malloc(sizeof(int *))
p+1 = &b[0];

これで良いですか?
>>69
自分でやってみたら?
>>69
めちゃくちゃ.
mallocはHeap領域にあるサイズの領域を確保してその先頭アドレスを
返す。そのアドレス値はプログラマは知らなくてもいい暗号アドレス。
それをp=&a[0]というヒープ領域には無い、つまりmallocで確保された
領域とは無関係な配列変数aの先頭アドレスで置き換えてしまっている。
mallocで得られたアドレスをこうして潰してしまうと、その値は永遠に
知る由もなくなる。ヒープで確保されたメモリはこうして開放されること
なく、プログラム終了までゾンビ状態でメモリリソースをただ圧迫する
だけの存在になってしまう。
やりたいことはpというint*型の配列へのポインタが指すp[0](int *型
変数)に&a[0]というアドレスを入れてやりたいわけね。
つまり
p[0]=&a[0];(もしくは*p=&a[0];)
p[1]=&b[0];(もしくは*(p+1)=&b[0];)
がより正しいということになる。
p+1=(int **)malloc....は滅茶苦茶
でコンパイルも通らない筈(アドレス値は左辺値にならない)
>>71
解ることは>>71の文章に無駄が多いという事でした
C言語のポインタって食べられますか?
>>73
C言語のポインタは垂らす調味料なので、少量しか食べられません。
たくさん食べると体調不良になります。
>>71
まさにその通りだけど、初心者にはわけわからんと思われ。
7664:03/11/28 20:36
>>71 これについて考えるので、ちょっと時間を下さい。
また明日レスします。
>>76
無理に背伸びしなくていい

簡単に言うと

「出来るか」「出来ないか」だろ?

>>64の疑問は「出来ない」の方、解決法を見出せばわからなかったことが解るかもしてないぜ
int X = 5;
char Y = 'a';

宣言した変数をメモリ上でイメージすると下記になる。

メモリ番地 変数名(別名) データ
1番地   (int) X    5
2番地   (char)Y   'a'
3番地・・・
(積んでいるメモリによって総番地数は異なる)

そこで
int *a = &x
とした場合、int型のポインタ(番地)を扱う変数にX(変数名)の番地を入れるという意味になる。
その結果、ポインタ(番地)を扱う変数は
a  → 1番地
*a → aの指し示す番地の内容(5)を表す。
のように使われる。
そして、
char *b = z
においては、charとintでデータを入れるのに要するメモリ数が異なるためこれは実行できない。
7978:03/11/28 22:04
第二段。
int p[n]のpはポインタ定数です。
イメージとしては
メモリ番地    変数名  データ
1番地   p[0]==p+0番地  1
3番地   p[1]==p+1番地  2
5番地   p[2]==p+2番地  3
です。
pは1番地を指すポインタ定数です。
それ故、(ありえない話ですが、メモリ内が仮に空だと仮定すると)
int *pp = p[0];とすると、
*ppのpp=00000001番地
p[0]=00000001番地
*ppのpp+1=00000003番地
p[1]=00000003番地
となります。

>>78で説明したようにcharとintでは使用するメモリ領域が違います。
具体的に申しますと、charは1byte、intは2byte使用します。
それはアセンブラや機械語をされたかたはご存知かと思いますが、実際には
1番地 2番地
3番地 4番地
・・・・
のようにメモリが論理的に配置されている為、上記にあわせると
1番地       2番地
  (int型の数値)5
3番地       4番地
'5'         'X' ※3,4番地は別のchar型の変数領域
となります。一番地につき1byteです。
8079:03/11/28 22:15
第3弾
mallocはイメージとしてはメモリ内に固定領域をプログラマが任意に取ることができます。
malloc(sizeof(int))ならばint型のメモリ上のサイズは2byteですので、2byte分のメモリを
開いている領域に確保します。

0番地 変数Xの値が入っている
1番地 空
2番地 変数Zの値が入っている
3番地 空
4番地 空

上記のようにメモリが開いていたと仮定するならば、
>>79の各型のメモリ使用を考慮して、1番地では1byteしか空いていないので
3,4番地の連続領域を利用します。
そしてmalloc(sizeof(int))の戻り値として「3番地」というポインタ(番地)を
返します。
そのため、受け取り側は
int *pointer;
pointer = malloc(sizeof(int));
と受け取ります。
ところが、>>69のような場合、
pointerには3番地が入っていますので、(左辺に計算云々は置いておいて)
3番地+1(1は左辺の変数のサイズにより可変。intの場合は2番地ずつ)=5番地となります。
>>69を例にしますと、
pointer + 1;
pointer = (*int)(malloc(sizeof(int));
であり、論理的には問題ないと思います。
しかし、現実にはこのように何が入っているかわからないような危険な事は避けた方が良いでしょう。
くそスレだったはずなのに、いつのまにかマジレスで埋まり始めたね。
8280:03/11/28 22:18
第4弾
ちなみに
*pointer;
pointer = (*int)malloc(sizeof(int));
の(*int)はキャスト演算子です。
キャスト演算子とは右辺の値をキャスト(変換)して左辺に代入します。
int n = 0;
float f = 1.5;
n = (int)f;
としますと、floatで表された浮動小数点が小数点以下で切り捨てられ
n == 1 となります。
あとは構造体の説明が終われば>>69さんもばっちりですね。
8381:03/11/28 22:32
第5弾
構造体について。
構造体とはイメージとしてユーザー定義の変数の型です。
struct おいらが自由に作る型 rei{
 char name;
 int age;
 char address[50];
 struct おいらが自由に作る型 *free;
};

今まで利用していたint型やchar型というのはC言語側が勝手に作った型で使い勝手が悪い事があります。
例えば、double以上の精度の浮動少数(バイト数が多いほど高精度)を扱いたい場合や、違う型を複数持つ多次元配列などです。
そういう時に「既存の型を組み合わせて自分の好きな型を作れれば・・・」という期待に答え(?)
構造体が実現されています。
上記の例は複数人いる人のデータを入れる変数の型に使えますよね。

ポインタを使う場合も今までのポインタ変数と同じく、
struct 自分で作った型 *pointerとしてその構造体の位置を示すポインタを入れる変数を作る事ができます。
また、構造体では既存の型のように
struct おいらが自由に作る型 任意の変数名
でいくらでも同じ型の変数を作る事ができます。

なお、構造体の中の自分の型と同じポインタは簡単に説明すると、「リスト構造」などを利用する際、構造体の中で自分と同じ構造の
ポインタを使うと色々便利なことができるのです。(詳細は別途調べてね♪)
8483:03/11/28 22:34
うわーん、名前の番号がずれてる・・・
・・・
・・・
・・・
ごめんなさい、飽きました。

間違っていたら本職のプログラマさん訂正してやってください。
学生さんは学校の卒業制作で忙しいのでJava初心者スレに戻ります。
じゃね。
8564:03/11/29 01:39
#include <stdio.h>
#include <stdlib.h>
#define test_size 5
main(){
    char a[test_size] = "a_ary";
    char b[test_size] = "b_ary";
    char c[test_size] = "c_ary";
    char d[test_size] = "d_ary";
    char e[test_size] = "e_ary";
    char f[test_size] = "f_ary";
    char g[test_size] = "g_ary";

    char **p;
    int m,n;

8664:03/11/29 01:39
    *(p+0) = (char *)malloc(sizeof(char *));
    *(p+0) = &a[0];

    *(p+1) = (char *)malloc(sizeof(char *));
    *(p+1) = &f[0];

    *(p+2) = (char *)malloc(sizeof(char *));
    *(p+2) = &c[0];
    

    for(m=0;m<3;m++){ /*3登録*/
        for(n=0;n<5;n++) /*1登録につき5文字*/
            printf("%c",*(*(p+m) + n));
        printf("\n");
    }
    return 0;
}

実行結果
>*.exe
a_ary
f_ary
c_ary
8764:03/11/29 15:36
>>85 malloc確保領域をつかっていない状態に
してしまいました。もう一度考え直します。
8864:03/11/29 16:54
アドレス番地[ 格納数値 ]
char ***p
char str_a[str_size] = "str_a group0 "


index_groupX          group1_strX                            strX

p+0[ *(p+0) ] 
p+1[ *(p+1) ] -> *(p+1)   [ *(*p+1)          ]
.            *(p+1) + 1[ *(*(p+1) + 1) = str_X]  ->  *(*(p+1) + 1) == str_X[ *(*(*(p+1) + 1)) == str_X[0]    ]
                                      *(*(p+1) + 1) + 1   [ *(*(*(p+1) + 1) + 1) == str_X[1] ]
8964:03/11/29 16:57
/*
index_groupX
    group0_strX
        str_a
        str_f
        str_c
    group1_strX
        str_b
        str_c
        str_g
*/
#include <stdio.h>
#include <stdlib.h>
#define str_size 16

main(){
    char str_a[str_size] = "str_a group0 ";
    char str_b[str_size] = "str_b group1 ";
    char str_c[str_size] = "str_c group0,1";
    char str_d[str_size] = "str_d other ";
    char str_e[str_size] = "str_e other ";
    char str_f[str_size] = "str_f group0 ";
    char str_g[str_size] = "str_g group1 ";

    char*** p;
    int l,m,n;
9064:03/11/29 17:01
/* index_groupX group0〜1の領域 */
    p = (char ***)calloc(2,sizeof(char **));

/* group0,1_strX strXの3つ分の領域 */    
    *(p+0) = (char **)calloc(3,sizeof(char *));    
    *(p+1) = (char **)calloc(3,sizeof(char *));

/* group0にstrXを登録 */
    *((*p+0) + 0)=str_a;
    *((*p+0) + 1)=str_f;
    *((*p+0) + 2)=str_c;

/* group1にstrXを登録 */
    *(*(p+1) + 0)=str_b;
    *(*(p+1) + 1)=str_c;
    *(*(p+1) + 2)=str_g;
9164:03/11/29 17:02
   for(l=0;l<2;l++){   /*   group0〜1   */   
      printf("group:%d\n",l);
      for(m=0;m<3;m++){   /*   1つのgroupにつき3つのstrX   */
         printf(" ",m);
         for(n=0;n<str_size;n++){   /*   1つのstrにつきstr_sizeの文字数 */
            printf("%c",*(*(*(p+l) + m) + n));
         }
         printf("\n");
      }
      printf("\n");
      printf("\n");
   }
   return 0;
}
9264:03/11/29 17:05
実行結果

group:0
     str_a   group0
     str_f   group0
     str_c   group0,1


group:1
     str_b   group1
     str_c   group0,1
     str_g   group1
9364:03/11/29 18:34
>>88-92
このcalloc領域は、有効に活用されているでしょうか?
その他にも何か気付いた事があれば、レスして欲しいです。
9464:03/11/29 18:35
char ***p;
このように宣言した場合、
&p番地に(char ***)型のp領域が生成される。
しかし、&(p+1)番地に(char ***)型のp+1領域は生成されない。
ょってpは左辺値になり、p+1は左辺値にならない。

p+1,p+2等は連続性のある領域確保(配列、calloc)の時だけ存在する。その並びを進んでいくから。
その歩幅は、(char **)*p領域を刺すのであれば、(char **)分だけ進む事となる。

このような理解で間違えていないでしょうか。アドバイスして頂けると有りがたいです。
9564:03/11/29 18:36
age。
>>94
>char ***p;
>このように宣言した場合、
>&p番地に(char ***)型のp領域が生成される。

&p番地って? おかしな解釈はやめたほうがいいぞ。ちゃんと初心者用の入門書を買って読め。
あと、何も「生成」はされないぞ。
9764:03/11/29 22:00
>>96
> &p番地って? 何も「生成」はされないぞ。

記憶領域が生成されるから、そこへアドレスを代入できるのでは,ないでしょうか?
p = malloc(char);
ポインタって、還元率は何パーセントですか。
20%くらい還元してくれたらうれしいな。
それとどこの店でもポインタは使えますか。
ゴールドポインタカードって誰でも作ることできますか。
× &p番地に(char ***)型のp領域が生成される。
○ ある領域が(char***型の)pの為に割り当てられる

? しかし、&(p+1)番地に(char ***)型のp+1領域は生成されない。
あまりにも当たり前というか関係が無さ過ぎ。
まるで「今日ラーメンを食べても明日は晴れになるとは限らない」とでも書かれてるようだ。
わざわざこんな事を表明したり確認したりするのは勘違いの種が植えられている証拠。

? p+1,p+2等は連続性のある領域確保(配列、calloc)の時だけ存在する。
もっとシンプルに考えるべき。ポインタがするのはあるオブジェクトを指し示す事だけ。
領域が確保されているかどうかは別の話。

? その歩幅は、(char **)*p領域を刺すのであれば、(char **)分だけ進む事となる。
何が言いたいのかこの文章からだと正確に意味を汲み取れない。
コミュニケイションは大事なので表記法には気をつけましょう。
char***型の変数に+1するとsizeof(char**)の分だけ値が増えると言いたいのでしょうか?
10064:03/11/30 11:43
>>99 res有難うございます。

p+1の確認について:
私の書きこみ>>69にて、p+1 を左辺値として誤用してしまい、
それに対して>>71等からアドバイスして貰いました。
そういう事が以前にあってp+1の事についての考えを書きました。
10188:03/11/30 16:20
>> p+1,p+2等は連続性のある領域確保(配列、calloc)の時だけ存在する。

>もっとシンプルに考えるべき。ポインタがするのはあるオブジェクトを指し示す事だけ。
>領域が確保されているかどうかは別の話。

領域確保とポインタは別の話ですね。
10288:03/11/30 20:22
>>99
> char***型の変数に+1するとsizeof(char**)の分だけ値が増えると言いたいのでしょうか?

その事が言いたかったのです。「(char **)*p」というのは、char**型の*pという事を示したかった
のです。キャストで書いておけば、変数名とその型の2つを表現できると思ったので。
このような表記法は、伝わりにくいですね。気を付けます。
int i, n[5];
for(i=0; i<sizeof n; i++)
 i[n] = 0;
のようなコードを書いて新人を混乱させるのが僕の唯一の楽しみです。
>103
それで混乱させれるの?
ばぐるやん
頭のおかしい先輩と思われるだけのような・・・
ヒネルにしてももう少し知的なコードの方が。
107デフォルトの名無しさん:03/11/30 22:48
>>103
i<sizof n
って、君配列を勉強しなおしなさい!
108デフォルトの名無しさん:03/11/30 22:53
俺の環境だとsizeof nは20だ。
iが配列じゃなくてもできるの?
110デフォルトの名無しさん:03/11/30 22:57
>>109
n[i]==*(n+i)==*(i+n)==i[n]
それ以前にかっこが無いだろ。
>>110
すごい、こんな使い方初めてしりました。感動です
この間その話題のときに初めて覚えて嬉しくてたまらないアホ発見。
>>111
sizeof は予約語だから()いらないよ
115デフォルトの名無しさん:03/11/30 22:58
>>111
sizeofのことか?括弧が必要なのは型のサイズを知りたいとき。つーか型の時はキャスト式だから括弧が必要なだけ。
116デフォルトの名無しさん:03/11/30 22:59
n[5]に値が入ってなくても良いのですか?
>>103
そりゃ混乱するわ。
i < sizeof n / sizeof n[0]
>>116
なにゆってる?
sizeof int == 1なんだろ
120デフォルトの名無しさん:03/11/30 23:29
>>119
そう決まっているわけじゃないから、やっぱりダメ。
ぬるぽ
ガッ
123デフォルトの名無しさん:03/11/30 23:35
sizeof nはいくつですか?
124デフォルトの名無しさん:03/11/30 23:39
20
5
160
127デフォルトの名無しさん:03/11/30 23:44
お前らほんとバカだろ?
ポインタのポインタのポインタのポインタ
void f(int n[])
{

int i;
for(i=0; i<sizeof n; i++)
 i[n] = 0;

}
のようなコードを書いて新人を混乱させるのが僕の唯一の楽しみです。
       Oノ
       ノ\_・’ヽO.←>>128
        └ _ノ ヽ
            〉
131デフォルトの名無しさん:03/12/01 00:31
ポインタのポインタのポインタをポインタにして
そのポインタのポインタをポインタのポインタに
ポインタのポインタのポインタとしてコピー
関数へのポインタの定義はなかなか覚えられん。
133デフォルトの名無しさん:03/12/01 01:59
関数へのポインタの配列へのポインタってどうかくの?
134デフォルトの名無しさん:03/12/01 02:25
こうやって
135デフォルトの名無しさん:03/12/01 02:39
ばかはひっこんでてね
>>133
そのままじゃん
void (**pf)(void);
void(*p[])(void)
138デフォルトの名無しさん:03/12/01 03:19
void(**p[])(void);
>>137,138
それ配列です。
ポインターの何が難しいのか理解できない。
void(*(*p)[])(void);
142デフォルトの名無しさん:03/12/01 03:34
>>133==140
>>140
一生ぼいんたんと遊んでろ
int A;
int*pA = &A;
int**ppA = &pA;
int***pppA = &ppA;
int****ppppA = &pppA;
>>144
わかりやすいサンプルですね
>>140
使い方をあまり知らないから「ね、ポインタって
難しいでしょ?」と言われると納得してしまいます。
ポインタだけが難しいという勘違いをするわけです。
未知の事なんて何でもかんでも難しいし、慣れない
テクニックを利用するのはややこしいものなんです。

だれか先人の中にポインタで極端に苦労した人がいたんでしょう。
>>146
あなたみたいな人です
"Cの"ポインタを根本から理解してない奴は、よく>>146なことを言う。
ポインタに限らないな

数学の数列が難しいというやつとかと似てる
int A;
int &rA = A;
int *pA = &A;
int *&rpA = pA;
変な例かもしれないけど、自分は先にアセンブラ覚えたけど、
そのときポインタといえばインデックスレジスタを指すていう
前提でやってたから、C言語のポインタはなんか違和感があって
すんなり使えなかったです。
152でません:03/12/02 04:18
んーーーー
んーーーー
んーーーー
#include <stdio.h>
int main(void){
    int week;
    char *WeekName(int);
    for(week=0;week<7;week++){
        printf("loop (%d) [%s]
            *WeekName:(%d)(%d),  *WeekName(week):(%d)(%d)
             WeekName:(%d)(%d),   WeekName(week):(%d)(%d)\n"
            ,week
            ,WeekName(week)
            ,sizeof(*WeekName),(unsigned int)*WeekName
            ,sizeof(*WeekName(week)),(unsigned int)*WeekName(week)
            ,sizeof((unsigned int)WeekName),(unsigned int)WeekName
            ,sizeof(WeekName(week)),(unsigned int)WeekName(week)
        );
    }
    return 0;
}

char *WeekName(int nn)
{
    static char *name[] = {
        "Sunday","Monday","Tuesday","Wednesday",
        "Thursday","Friday","Saturday"
        };
    return((nn<0 || nn>6) ? name[0] : name[nn]);
}
153152:03/12/02 05:04
WeekName(week) で参照できるのは
ポインタの指す、文字列のあるアドレス

*WeekName(week) で参照できるのは、
ポインタの指す、文字列の先頭一文字のデータ

printf関数の%s変換は最初からポインタを引数にするようになっているので
アドレスを指すポインタを引数に与えると、
そのアドレスにある文字列が表示される。

他は、なんか値があるけど、関係ないので、この際気にしない。

unsigned intの値を表示するための
printf関数の変換指定文字は%dでなくて%uでした。
たまたま負の値が出なかったので、警告されなかったようです。
ポインタ専用の%pというのもあるようです。

汚しまして失礼。
それでは、ばかは、ちょっとだけ出たので、寝ます。
        printf("loop (%d) [%s] \
            *WeekName:(%d)(%d),  *WeekName(week):(%d)(%d) \
             WeekName:(%d)(%d),   WeekName(week):(%d)(%d)\n"
ポイソタって食べ物でつか
おまえらはどっち

(1) int *a;
(2) int* a;
おまえらはどっち

(1) int *a, *b;
(2) int* a, b;
>>157
その1と2は意味が違うぞ。
おまえらはどっち

(1)(´Д⊂ヽ
(2)(つД`)
(; ・`д・´) !? (`・д´・ (`・д´・ ;)
161945:03/12/05 18:14
>>160 そんな大勢で悩むほどのもの?? w
>>156
関数の戻り値にポインタがあった場合は(2)、通常は(1)

int* CreateInt()
{
  int *p = malloc (sizeof int);
  return p;
}

といった感じ
int *を返す二つの関数のプロトタイプ宣言を並べたいときは?
int* foo(void),* bar(void);
並べるやつがわるいのか?
>>163
そいつは氏んだほうがいい
一貫性の欠如
>>156
int*型のaを宣言しているのであって、int型の*aを宣言しているわけではないと言う
意味合いからは(2)。
>>157
間違いを起こさないためには(1)。

と言うのを天秤にかけ、ポリシーよりも安全性を選ぶ俺は(1)。
>>166
一貫性の欠如
>>156
仮引数の時だけint* a;にしてる
一貫しているとでもいってほしいのか?
int *a
で混乱するのはCに不慣れな初心者だけだろ。
int* a,b;
なんてやるのもね。
>int *a
>で混乱するのはCに不慣れな初心者だけだろ。
で混乱するのはおかしくない?

むしろ
>int* a,b;
>なんてやるのもね。
コレはかなり禁止だろう。
見た目悪すぎ
>>170
初心者にポインタを分かりにくくしている原因の一つかもね。
int* a;
しか許されてなかったら、初期化してないポインタに対していきなり代入
*a=0;
という誤解は減ったかも。
int* a
という表記は考え方としては間違ってはいないが
実際にコードとして書くのは(文法的には正しいとしても)明らかに間違い。
なぜなら
int* a, b
が期待した挙動を示さないから。ゆえにどんな場合でも
int *a
と書くべき。ケースによって
int* a
int *a
を使い分けるメリットは皆無。逆に表記の一貫性を損なうというデメリットしかない。
C言語はセンスの捻じ曲がった人間が開発した以上(素人の)常識は通用しない。郷に従うのが筋。
これに反論する奴は
#define BEGIN {
#define END }
とかやってる奴と同類。
>>174さんは話が通じそうでよかった

>>162の考え方はどうでしょうか?
176デフォルトの名無しさん:03/12/06 23:48
C言語のポインタに関して、アセンブラをやっとくと解かり易いって聞いたんですが、
もしかしてアセンブラ命令の
LAD GR1,A
とかそんな感じの事でしょうか?
確かにポインタと酷似してるんですが・・・
アセンブリ言語のどの命令、って訳ではないんじゃない?
大体いろんなアセンブリ言語あるし。
アドレスとかデータとか、間接アドレッシングだとかラベルだとか、
その辺使ってれば容易にポインタなど理解できると言う意味では?
>>176
だまされてるだまされてる
179デフォルトの名無しさん:03/12/07 00:10
>>177
要は慣れよ、と、こういう事ですね・・・・
>>178
ズガーン
あんまり説得力ないなぁ。

int *a
という表記は考え方としては間違ってはいないが
実際にコードとして書くのは(文法的には正しいとしても)明らかに間違い。
なぜなら
int *a, b
が期待した挙動を示さないから。ゆえにどんな場合でも
int *a もしくは int* a
と書くべき。ケースによって
int* a
int *a
を使い分けるメリットは皆無。逆に表記の一貫性を損なうというデメリットしかない。
C言語はセンスの捻じ曲がった人間が開発した以上(素人の)常識は通用しない。郷に従うのが筋。
これに反論する奴は
#define BEGIN {
#define END }
とかやってる奴と同類。
181175:03/12/07 01:25
>>180
がもう一回出してくるから良く読んでみたら

最後の方は理論が通ってるが前半は合わないや

int* a;
これは邪悪なのでやめたほうがいい

int* a, b;
*がどちらへかかってるのかわかりづらい

int *a, b;
とやって a がポインタである事を明示的に示すべき

int *a;
int b;
とやるべきでもあるかも知れない
182デフォルトの名無しさん:03/12/07 01:37
Cの構文がもっとすっきりしていたら
初心者の混乱も少なくて済んだのにね
ちなみにvcで自動生成されるコードの多くは
hoge* hoge;
>>181
いやー、論旨をひっくり返そうとしたけど失敗したんだよ。
気にしないで。
185140:03/12/07 01:52
int* n; C++的。
int *p; Cプログラマーに多い。要するに古い。
int* p,n; コレの意味が同型だと理解するようなやつは一から勉強しなおせと言いなくなる
で結論は最初はスタイルなど気にせずわかりやすい意味のある変数名、関数名などでプログラムを
組んでいくほうが後々のためだと思うのだが。エレガントなプログラムなんて後からついてくるもの。
と、俺は考える。
普通ポインタはtypedefすると思うが。
typedef int *pint;
pint p,n;
>>181氏の考えに続いて

ゆえに

int *a;
int* a;

どっちでもいい、と考えてみる 1変数宣言派はいないかなぁ。
188初心者:03/12/07 02:03
そうする機会はありそうです。感謝。
なんで気付かなかったんだろ?
ブレインファックやれば?
190175:03/12/07 11:22
>int *a;
>int* a;
>
>どっちでもいい、と考えてみる 1変数宣言派はいないかなぁ。

なんでこだわるかというと、
>int* n; C++的。
>int *p; Cプログラマーに多い。要するに古い。
>int* p,n; コレの意味が同型だと理解するようなやつは一から勉強しなおせと言いなくなる

一番↓の通り、同じ型に”見える”。
わざわざ解りにくいように作る必要は無い。

言語によっては int* a, b; とやって intを指すポインタ a と intを指すポインタ b って同じように創られるものもある
つまりCで言うところ
[int* a b;] が [int *a, *b;]という意味になる

でもCは違うので、変数ごとに解りやすくやったほうがいいわけ
>>int* n; C++的。
ハァ?
いいじゃんどっちでも。とっとと仕事しる。
結構くどいね。
>>191
あつてるだろ。参照はほとんどそれ。
195デフォルトの名無しさん:03/12/07 13:28
ポインターに整数入れるの方が馬鹿。
>>194
妄想はいいから
>>int* n; C++的。
の根拠を示せ。
& じゃなくて * のな。
両方に対応できて区別できる能力が必要。
書き方に こだわりすぎると
他人のソースも ろくに読めなくなるんじゃね?
199194:03/12/07 13:56
>>196
その根拠? C++的の言葉じたい抽象的、
その言葉を >>196 がどう捉えているか知らんが
俺はC++でその表記が多いと感じたまで。
200デフォルトの名無しさん:03/12/07 14:12
200
でも、キャストするときは(int*)だよな…
202デフォルトの名無しさん:03/12/07 14:21
関数へのポインタについて教えてください。
質問を教えてください
割れずください
翼を下さい
206デフォルトの名無しさん:03/12/07 14:46
>>174
そういや、そうだなぁ。

今度 C++で
int* a;
の表記をしようと思っていたがやめた方が吉なのか。

この板でそういう記述の人がいて、みてみると
なるほど、その方が合理的だよなぁと思ったんだが
int* a, b; で b がポインタにならないのであれば
誤解を与えやすいな。

207デフォルトの名無しさん:03/12/07 14:50

ポインタは考え方よりも実際のコード(表記)で混乱することが多い。
K&Rにもよく理解できない複雑な事例が載っていたなぁ・・・

この辺を極める本ってあります?
K&Rはちと説明が簡素すぎてよく理解できなかったんだ。
そんなに間違えやすいか?
じゃあ int* p, n; とすりゃいい。
>>205
いま私の願いごとが かなうならば翼がほしい この背中に鳥のように 白い翼つけてください
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ行きたい

いま富とか名誉ならば いらないけど翼がほしい 子どものとき夢みたこと 今も同じ夢に見ている
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ 行きたい

>>206
いまだにそんなこといってるのか?

・1行に複数の変数を宣言/定義しない。
・変数を定義するときは可能なかぎり初期化する。

というのが、いまどき普通だろ。
>>210
俺はプロじゃないんで、よく分からんのですが
そういうもんですか。

ポインタと普通の変数を一緒に定義する時は
int *p, n;
単独の場合はint* p;にしている
一貫性がないが、場合分けの基準は一貫しているので問題ない。
一緒に宣言する変数を増やしたくなったり、
減らしたくなったりしないのか?
それぞれが「俺が普通だ!」と言うスレ
215新人:03/12/07 16:42
int *p,n;
だよ〜
216デフォルトの名無しさん:03/12/07 17:39
>>207
秘伝C言語問答 ポインタ編 柴田望洋
俺はどうでもいい変数以外init a,b,c;見たいな書き方せんな。
 int a; // コメント
 int b; // コメント
見たいな書き方が多い。i,j等のループに使うどうでもいい変数だけは
羅列することが多い。ポインタの場合、どうでもいいポインタって俺の使い
方ではほとんど無いから羅列したことは無い。
そんな俺は
int* a;
と宣言する派。
>>217
あぁ、専門学校だろ?
専門学校はコメントを良く書けといわれるらしいな
>>218の言っている専門学校ではそういう風に習うんだ…
変数名がコメントを兼ねるように書けばいいだけ
>>219
うん、そうみたいね。
俺も通ってるわけじゃないから詳しい事は解らないけど
聞いた話によると就職にコメントが詳しく書いてあると有利らしい

ときどきは間違ったプログラム、つまり期待してた動作をしなくても入社できるらしい
うわ〜。うそ。変数名それぞれにコメントかいたってしょうがないべな。
そんなことしたら変数名の意味がなくなるし。
>>220
つまり
int comment_count;
char comment_str;
とかにするって事?

とボケてみたけどレベルいくつでしょう?
>>220
ってゆーか
int loopCounter_1_to_10_forUse_arrayTbl;
char *errorMessage_pointer_for_get_functionReturnStatus;
とかなら俺は嫌。

もっとも
int l; /* arrayTbl[]用に1から10の値で使うループカウンタ */
char *m; /* 関数を呼び出した際、エラーメッセージを受け取るポインタ */
とかだとさらに嫌

ここにまとまってますが。
ttp://www.tetish.com/english%20pointer.htm
226デフォルトの名無しさん:03/12/13 19:49
>>217
ループだけに使う変数は、柿のように使うのはどうでしょうか?


{int a; for(a…){

}}
int * const a;
int* const a;
int *const a;
int*const a;
どれが好み?
#define CPINT int*const
CPINT a;
CPINT a, b;
>>229
それやったらやっぱbはポインタじゃなくなるんですか?
いいえ
>>231
いいえ。
typedefじゃないもん。
>int * const a
こんなんはじめて見た。
ポインタの中身じゃなくて、ポインタそのものの値が固定になるのか?
短い範囲のforループ変数はiとかjとか使ってる
判定条件の変数にちゃんと名前が付いてれば何のループかすぐわかるじゃん。
ループ変数だと一目でわかんない名前の方がもっとイヤ
>>233
その通りだ。因みに
const int * a
int const * a;
この二つは、同じだ。
236デフォルトの名無しさん:03/12/14 22:24
ポインタ難しいいいいいいいいいいいいいいいいいいいいいいl490わうmんふぉいさ@yfr987wqrfgth97wt3qlkじょkさfじヴぉあsAAAAAAAAAAAAAAA””””!!!!!!!「
237デフォルトの名無しさん:03/12/15 14:14
役に立つか立たないかは置いといて、以下のようなこと出来る?

#include <stdio.h>
void main (void)
{
  char a,b,c,null;
  a = 'a';  b = 'b';  c = 'c';  null = '\0';
  int txt =a<<24 | b<<16 | c<<8 | d;
  char *str = (char *) txt;
  printf ("%s\n",str);
}

これで、abc と出力できる?
コンパイルエラー
#include <stdio.h>

void main (void)
{
char a,b,c,null;
int txt;
char *str;

a = 'a';
b = 'b';
c = 'c';
null = '\0';

txt = null<<24 | c<<16 | b<<8 | a;

str = (char *)(&txt);

printf("%s\n",str);
}

うちの環境だとこれでいけた。
240デフォルトの名無しさん:03/12/15 14:47
ああ、そうだった。
char *str = (char *) txt;
じゃなくて、
char *str = (char *) (&txt);
か。
それと、
int txt =a<<24 | b<<16 | c<<8 | d;
じゃなくて、
int txt =a<<24 | b<<16 | c<<8 | null;
だった。
でも、できるのかなあ?
>>237
int が 32bit なら
  int txt =a<<24 | b<<16 | c<<8 | d;
        ↓
  int txt = ntoh(a<<24 | b<<16 | c<<8 | d);

で出来るだろう。
やっちまったよママン…
× ntoh
○ ntohl
警告: 代入により、キャストなしで整数からポインタを作りました
警告: 代入により、キャストなしで整数からポインタを作りました
警告: 代入により、キャストなしで整数からポインタを作りました
警告: ポインタと整数との比較を行なっています
警告: ポインタと整数との比較を行なっています
警告: ポインタと整数との比較を行なっています

”警告”とは?

柔道のルールに反する様な危険な行為を故意に行った、
故意に場外に逃げる行為を行ったなどと審判が判断すると、
その程度により、注意、警告を宣告されます。あまりにひどい行為の場合は、
即「反則負け」となります。

*「警告」は「技あり」を1つ取られたのと同じ扱いになります。
そこそこうけた
245デフォルトの名無しさん:03/12/16 03:37
ポインターが、あると何ができるようになるんですか?
もしくは無いとできない事ってなんですか?
口座を用意しておくとお金を振り込んでもらえる

振込先が分からないので使えるお金がない。。。
247デフォルトの名無しさん:03/12/16 05:03
>>246
int a; /*口座を作る*/
a=10; /*口座に振り込む*/

じゃダメなん?
これだと口座10に移動した、とかって事になるのか。
マジ質問なの?

マジレスするなら、aに振り込んでくれという人と、bに振り込んでくれという
人がいるとき、振る込む人にどこに振り込むかおしえるのにポインタが使える。
>>237>>240
正直、「そんな事をするな!」と言いたい。
250237:03/12/16 12:45
家にはネットにつなぐ環境がない。
家に帰ってコンパイルしてみたら、>>239の方法でコンパイルできた。
何でこうなるの?
http://homepage1.nifty.com/~umetani/ims/2002/20020319001/0.html
↑のエンディアンというものに関係があるのでしょうか?
>>250
そーでつ。
ポインタの概念は理解できても表記方法がサッパリ覚えられん
どうやって覚えたの?
考えてる暇に書きまくる
>>253
英語でポン。
C言語完全制覇より抜粋
int *ap[10]; ap is array of pointer to int.「apはポインターへの配列(要素10)です」

int (*pa)[10]; pa is pointer of array to int. 「paは配列(要素10)へのポインターです。」

int (*fnp)(double);
fnp is pointer to function(double) returning int.「fnpはintを返す関数(引数double)へのポインターです。

こんな感じで解釈するみたいです。
>C言語完全制覇より抜粋
C言語ポインター完全制覇の間違いね
257デフォルトの名無しさん:03/12/20 13:04
定番
void (*signal(int, void (*func)(int)))(int);

signal is a function(int,func is a pointer to function(int) returning void)
returning a pointer to function(int) returning void

ここで、a pointer to function(int) returning voidをtypedefするとわかりやすい
typedef void (*HANDLER)(int);

HANDLERを使うと、上記の英文は次のようになる
signal is a function(int,func is HANDLER)
returning HANDLER

Cの構文で表すと
HANDLER signal(int,HANDLER func);

ここまで整理されるとやっと意味がわかる。
258デフォルトの名無しさん:03/12/20 23:51
↓のhogeって、結局何なの?

void *(*hoge[])(int)(char *);
259デフォルトの名無しさん:03/12/20 23:53
訂正です。↓
void (*(*hoge[])(int))(char *);
hogeはポインタの配列・・・
>>255
その本最悪だな。俺なら
int* p; // p はintへのポインタです。
int* pArray[10]; // pArray はintへのポインタの(10個の要素を持つ)配列です。

微妙に外れるが配列の書法と関数ポインタの書法は失敗だったと
Cを作ったカーニハン博士自身も仰っている。
>>261
俺なら以下が何がいいたいのかわからない。

>>255の本のは
* と [] と () と型名とを「結合順に」「英語で」 読んでいけば理解できるってことだろ?
>>259
hoge is an array of a pointer to a function (int) returning a pointer of a function (char *) returning void

int を受け取って、char へのポインタを受け取って void を返す関数へのポインタ、を返す関数
へのポインタの配列
264255:03/12/21 02:55
>>257
たしかにtypedefははずせないね。
とくにc++でtemplate使った構文を作るときになんかないと不便ですね。
>>262
そうそう大事な事書き忘れてた。
>>263
日本語訳こちらの方がよくない
hogeは返り値無しの関数(引数char*)へのポインターを返す関数(int)へのポインターの配列
265デフォルトの名無しさん:03/12/21 10:04
英語で解読するメリット
1.結合順位に従って読み下した順番に並べていけばいいこと。
  (日本語だと、日本語の言葉の順番は逆なので、頭の中で並べ直さないといけない)
2.語順は結合順なので、何通りにもなることはない。
  (日本語だと>>263>>264のように、同じhogeを扱っているのに、いい訳と悪い訳ができることがある)
3.[]を見たらarray of〜、*を見たらpointer to〜、()を見たらfunction(〜)と言った具合に、機械的・反射的に探すことができる。
int* p; intへのポインタのp

先生!日本語で読めました!
>>266
だれも日本語で読めないなどは言ってないのですが。
なるほどなるほど…
dereferenceを逆参照とさえ読まなければ
英語だろうが日本語だろうがどっちでもいいよ。
ポインタが理解できないのは単に頭が悪いから。言語は関係ない。
>>269
というより語順をあわせたら
解かりやすくなるという物でもなさそう。。。
271デフォルトの名無しさん:03/12/23 11:55
Cの構文は右左に飛ぶから、読みづらい
272初心者:03/12/23 18:09
printf("\x1b[%d;%dH", y, x);
猫でもできる・・・であったプログラムなんですが
どうやらエスケープシークエンスがだめなんです。
どうしたらよろしいのでしょうか?
XP使っています。
273初心者:03/12/23 18:20
NULLって結局なんなんですか?

よくファイルオープンのあと
if ( fp == NULL )とか
if ( !fp )とか書いてあるんですが
○チはいらんのだよ
>>273
>NULLって結局なんなんですか?

ヌルポインタ
つまりNullPointerExceptionとは、

int *a=NULL;
*a = 10;

みたいなことをやると起きるの?
>>273
初期化されてないポインタの中には適当な値が入ってます。
だからポインタが何処も指していない状態を厳密に示す
ために値としてNULLを入れてやります。
例の「 if ( !fp ) 」が通用するのは、NULLは実際には
' 0 ' で定義されてたりする事が多いからみたいです。
あまり良くないのかも?それとも無問題?

・ポインタとかポインタへのポインタとか、とにかく戻り値がどこかのアド
レスな関数では、処理が失敗したときNULLを返すように作る事も多いです。
・特にどこも指し示していないポインタはヌルポインタとして初期化します。

こんな感じで良いでしょうか?>>ALL
>>277
無問題
例えヌルポがオール0ビットで表されていなくても
「(void *)0」がヌルポになることが保証されている
さらに「if( NULL )」が偽と判断されることも保証されている

気をつける点は「#define NULL (void *)0」を使う事と
ポインタを渡すべきところに0を渡したりしないという事

後は放っておいても大丈夫
>>277
感謝!
280デフォルトの名無しさん:03/12/24 10:43
NULLの定義が入っているのってstdlib.hでいいんだっけ?
あと、どこにも向けてないポインタを使うと、
実行時エラーが出るけど、ゴミアドレスが、たまたまOSから見て、不正なアクセス領域を指してなければ、
エラーは出ないもんなの?
つまりゴミアドレスの内容によって、エラーが出たり出なかったりするのかな?
>>280
>NULLの定義が入っているのってstdlib.hでいいんだっけ?

sidio.hやstring.hにも定義されている

>どこにも向けてないポインタを使うと、

 どこにも向けてないポインタ=NULL

では?
2ちゃん語の「ぬるぽ」ってどういういみですか?
   ( ・∀・)   | | ガッ
  と    )    | |
    Y /ノ    人
     / )    <  >__Λ∩
   _/し' //. V`Д´)/
  (_フ彡        /  ←>>282
>>281
初期化していない、って意味かと。
だとしたら、

>>280
>たまたまOSから見て、不正なアクセス領域を指してなければ
問題なくアクセス出来るでしょう。読み取りデータには意味が無いですが。
ただし、読み取りは可能でも書き込みは出来ない領域なんてのがある
場合があって、そのときは他のエラーが発生するでしょうね。
>>284
「NULLで初期化する」という言い方もあるから
「初期化していない」ではないと思う。
>>285
馬鹿発見
>>286
馬鹿は認めるので、説明してください。
いったい何を説明して欲しいのだろう?
/*
* char型6つぶん calloc したつもりなのですが、
* scanfすると何文字でも入ります。
*
* この場合 6文字目以降は、
* はいることははいるけど、
* その後の運命は完全に無保証、ということでいいのでしょうか ?
*/

#include <stdio.h>
#include <stdlib.h>

int main(void){

    char *str;
    printf("宣言直後:%p\n", str);    /* gccだとこの時点でアドレスがある。*/
                    /* iccだと 空ポインタ */

    printf("calloc後:%p\n", str = calloc(6,sizeof(char)));
    
    printf("5文字入力_" );        /* char型6個ぶん確保したつもりなのですが、 */
    scanf("%s", str);        /* 何文字でも入ります */

    printf("%p %s\n", str, str);

    free(str);
    return(0);
}
/*
* とりあえずこんな感じで、希望の動作になりました。
* 惚け防止に最適 > Cげんご
*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
    char *str;
    printf("宣言直後:%p\n", str);
    printf("calloc後:%p\n", str = calloc(6,sizeof(char)));
    printf("5文字入力_ ");

    int i = 0;
    while(1){
        if(((*(str + i) = getchar()) == '\n')){
            *(str + i) = 0x00;
            break;
        }
        if(i == 5){
            puts("5文字に切り詰めます");
            *(str + i) = 0x00;
            break;
        }
        i++;
    }
    printf("入力後 :%p\n|%s|\n", str, str);
    free(str);
    return(0);
}
291デフォルトの名無しさん:03/12/25 20:42
>>285
>「NULLで初期化する」という言い方もある
のがわかっているなら、「初期化していない」ということになるだろう?
C言語というより日本語の理解の問題のような気もするが念のため

「初期化していない」
int *ptr;

「NULLで初期化する」
int *ptr=NULL;
292284:03/12/25 21:13
>>291
  「NULL 以外で初期化する」
  int *ptr = (int *)0x1000;

「初期化したけどどこにも向いていないポインタは存在する」
みたいな事を >>285 は言いたいんじゃないかと。

// でもそこで争う気はないんでスルーした次第。
おまいらNULLを指してるポインタと
ダングリングポインタの違いもわからないのですか?
お前はダングリングポインタが何なのか誤解してる
295デフォルトの名無しさん:03/12/26 09:18
ダングリングポインタって何ですか?
296284:03/12/26 09:39
>>294
正式な定義がどうかは知らないけど (あるの?)、世間的には
  1. 解放済みの領域を指すポインタ
  2. (1. に加えて) 関数が戻した、そのローカル変数へのポインタ
  3. とにかく何処を指しているか解らないポインタすべて
の 3種類あるよね。
俺の認識では 2. なんだけど。
>>296
http://dictionary.reference.com/search?q=dangling%20pointer
簡単に説明すると、かつては正しい場所をさしていたものが、
freeやreallocなどにより、有効なものではなくなり、宙ぶらりんの
状態になったものを言う。
なので、2,3は普通ダングリングポインタとは言わない。
case1:
char *p = malloc(1024);
free(p):
// now p is a dangling pointer

case2:
char *p = malloc(1024);
char *q = p;
p = realloc(2048);
// now q is a dangling pointer

case3:
char *p;
void foo()
{
char q[1024];
p = q;
// p is a valid pointer
return;
}

void bar()
{
// p is an undefined pointer
foo();
// now p is a dangling pointer
}
>>298
>p = realloc(2048);

どこを再確保する気?
300284:03/12/26 12:55
世間的にはどうか、ってのを置いとくと
実のところ 1. と 2. は区別する必要はないと
自分では思ってるんだけど。

そういや C++ だと、こういうのもあるね。

  const char *ptr = std::string("ABC").c_str();
  sprintf("%s\n", ptr); // pointed to temporary instance

>>297
で、そこは“普通”あるいは“正式な定義”なの?
# そもそも「正式」って誰が決めるんだろうね。
>>297
参照先の英文にはfreeともreallocとも書いていないのに、
freeやreallocに限定して、>296の2.を否定するのは作為的だな。
>>297>>301
[Jargon File]とあったのでnew hacker's dictionaryを見てみたらあったから、そのまま乗せるぞ

dangling pointer [原義:宙ぶらりんのポインタ]
n. 実際にはどこにもたどり着かない参照(Cなど一部の言語では、実際には何にも有効
なものを指していないポインタ)。指していた相手が移動したり消えたりしたために起
こるのが普通。この語は技術的は意味を広げてハッカー語として使われており、たと
えば、もう国の反対側に引っ越してしまった人の市内電話番号は宙ぶらりんポインタ
だ。dead linkと比較せよ。
>>301
296の2は、単なるinvalid pointer
>>300
別に「正式」なんぞを決める必要は無く、みんながどう使ってるかが問題なのでは?
ググればわかるだろ。
305デフォルトの名無しさん:03/12/27 13:51
>>289
いくらでも文字は入るけど、ヒープ領域をぶっ壊してるだけ

ポインタを宣言した時点では、どこも指していない。デタラメなアドレスが入っているだけで、有効なアドレスは指していない。
freeで解放した時点では、free解放直前までと同じアドレスが入っている。しかし、解放してしまえば、有効なアドレスを指しているとは言えない。

「ポインタを宣言したら、NULLを入れておく」、
「freeで解放したらNULLにしておく」、
といったように、これらのどこも指してないポインタを、プログラマが明示し、
このポインタを使用する関数に、ポインタがNULLのときは、エラーを返すようにする、
というのはよく使われる手段である。
>>305
たまたま有効なアドレスをさしているということはありえる。
>>272
あ、それね。
XPのcmd.exeは標準でANSI.SYSを読み込まないから、無理だよ。
漏れもconfig.NTにDEVICE文を付け加えてみたけど、どうも上手くいかない。
まあ、SetConsoleTextAttribute()を使いなさいってこった。
ポインタが無効になったらNULLを代入するのは良い手法だな。
エラーの発生ポイントをチェックできるし。
>>306
たまたま有効なアドレスをさしているということがありえるから、バグを見つけにくくなるわけで、
なら、最初っからNULLにしておけば必ずエラーになるからバグが見つけやすくなるというのが
>>305の言いたいことでないの?
>>309
何が言いたいのかは知らんが、間違ったことを言ってるから指摘しただけだ。
>>310
間違ったことって…
そんな重箱の隅をつついて初心者に対して難解な文章にする必要は無いだろう
>>311
君、技術者に向いてないよ。止めたら?
>>310,>>311
どっちにも頷いてしまう・・・
>>310
>何が言いたいのかは知らんが、間違ったことを言ってるから指摘しただけだ。
相手の言いたいことすら理解できていないのに、
発言する奴の方が技術者に向いていないと思うが?

因みに >>309 の言いたかったことを代弁すると・・・
「お前の指摘(?)は的外れ。出直して来い」
pt = 0;

if(!pt)
316310:03/12/28 03:30
>>314
>>312は俺じゃないんだが、それはおいとく。

314は312に向けた発言だと思うが、312がどれほど技術者に向いてなかろうが、
君の資質とは全く関係の無いことだ。もう少し冷静になって書き込めよ。

それに他人の代弁なんかする必要は無い。話がややこしくなるだけで、何の利益も無い。
317310:03/12/28 03:33
それに、いやに305の肩を持つが、305が何かすばらしいことでも言ってるのか?
Cプログラマであれば常識の範囲でしかないことだろう?
>>316
>それに他人の代弁なんかする必要は無い。話がややこしくなるだけで、何の利益も無い。

君、技術者に向いてないよ。止めたら?
319311:03/12/28 04:23
>>317
常識を知らんやつに常識を教え込んでいるのは素晴らしい事だろう
常識知らんプログラマに囲まれて仕事はしたくないぞ
香ばしいスレになってまいりました
>>319
で、常識を知らん奴に教えるときには、その内容にうそが含まれていてもよいとでも?
香ばしいなw
323デフォルトの名無しさん:03/12/29 06:09

関数・・・void func(int a[]) の引数にint型の配列s[]の先頭要素のアドレス・・・s(&s[0]) を渡せる理由が分かりません。
もちろんポインタ変数にアドレスを渡す方法なら余裕で理解できますが。こういうやつvoid func(int * a)
325デフォルトの名無しさん:03/12/29 09:16
にゃあにゃあ
326デフォルトの名無しさん:03/12/29 22:16
ポインタ理解不能
ポインタなんて分かっちゃえば簡単なのに
なんでそんなに逃げ腰なんだ
328アンチポインター:03/12/30 05:58
ポインタ変数をポインタと略すな。
アドレスをポインタと呼ぶな。
そもそもポ゚インターの概念を廃止するべきだ。
ポインタ==最強
>ポ゚インター
??
>>328
同意。混乱の素だよな。ポインタって禁止用語にすればいい。
>>327
トラウマ糞コード書く香具師がいるから。
ポインタでつまづいてるようでは一流のプログラマーにはなれませんか?
どこにもつまずかなくても一流のプログラマにはなれませんが
↑嫌われ者はどっかいけよ
↑実は>>334に夢中
配列とポインタの完全制覇
http://member.nifty.ne.jp/maebashi/programmer/pointer.html
「ポインタが難しいのではない。
C言語の、配列とポインタにかかわる文法が混乱しているだけだ。」
----
ガイシュツ?
>>337
>>255でおいらがしーぼん紹介してあげたんだな〜。
よって既出!!まあ。サイトまでは紹介してあげてなかったけどね。
/*
* 笑い話に出てくる、ポインタのポインタのポインタの...
* というのを実験してみた。
*/

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char test[] = "oreore";
    char **p    = calloc(1, sizeof(char *));
    char ***q    = calloc(1, sizeof(char *));
    char ****r   = calloc(1, sizeof(char *));
    char *****s   = calloc(1, sizeof(char *));

    *p = test; *q = p; *r = q; *s = r;

    printf("%s%s%s%s%s\n",test, *p, **q, ***r, ****s);

    printf("%p %p %p %p \n %c %c %c \n",
        test, p, q, r, *test, *(test + 1), *(test + 2));

    printf("%p %p %p %p \n %c %c %c \n",
        ****s, ***s, **s, *s, *****s, *(****s + 1), *(****s + 2));

    free(p); free(q); free(r); free(s);
    return (0);
}
>>339
何の実験だか知らないが、
> *p = test; *q = p; *r = q; *s = r;
ぬるぽ。
ちなみに俺のメモリー確保はmallocだ
ちなみに俺のプログラムは
#define malloc(n) calloc(1,n)
をコメントアウトすると動かなくなるんだ
343デフォルトの名無しさん:04/01/05 17:10
mov ax,word ptr ds:[dx]
>>343
16ビットモードだと dx による間接アドレッシングはできない。
bx, si, di のどれかにしろ。
345デフォルトの名無しさん:04/01/07 22:49
     ∧_∧
     ( ゚Д゚ ,,)  { ギコ猫だってCやるんだぜ。 )
  _ | ̄ ̄||_)_
/ /|――||/旦/|
| ̄| ̄ ̄ ̄ ̄ ̄| . |
|三|_____|/ カタカタ・・・・
>>328
>アドレスをポインタと呼ぶな。

呼んでない。
恐らく、そう呼んでいるのは理解してないヤシだけ。
347デフォルトの名無しさん:04/01/08 14:03
int* a,b;

ってやったらaもbもポインタになるようにしてほしい。
今さらそんな機能が追加されても、邪魔なだけ。
邪魔って言うか過去のソースが全滅しそうだな。
お行儀の良すぎるソースなら大丈夫だよ。
int i,j,k;
int *p,*q,*r;
こんなことしてるのは少数派だろうが。。。
おれの場合typedef使うからな
typedef int* inpee
inpee a,b;
typedef foo* fooptrとか大嫌いで存在すら認められないってのがいるからなあ。。。
>>352
そういう人はCのみで終る人生でありC++にステップアップできない人だからほっときましょう。
>>352
あー、俺もそれは嫌だな。
いちいち定義する必要があるのかと一晩中(ry
お前 * 見たくないだけちゃうんか、と。
イタイ
>>355
お注射しますか?それともフェラチ●しますか?
357デフォルトの名無しさん:04/01/10 14:04
教えてください
goto *(void (*)())0x6000;
と書いたときの動作と意味がわかりません。
アセンブラレベルでステップ実行してみなよ。
359デフォルトの名無しさん:04/01/11 18:32
引き数なし、戻り値なしの関数へのポインタ型に0x6000をキャストし、
0x6000の指すアドレスにジャンプせよ。
0x6000にはジャンプしないと思う
360デフォルトの名無しさん:04/01/11 18:45
>>1
ポインタは、アドレスを格納した変数のことだよ。
メモリに直接アクセスできるから、配列を使うより効率的なんだ。
>>360
> メモリに直接アクセスできるから、配列を使うより効率的なんだ。

こう信じ込んでいる奴って多いのか ?
>>359
0x6000にジャンプさせるには
goto (void (*)())0x6000;
じゃない?
手元にクロス環境がないのでわからないけど。
>>361
それはそれで正しいんじゃない?

int f(int *****ap, int n)
{
  int a;
  for(a=0;a<100;a++){
    int ****bp=*(ap+n), b;
    for(b=0;b<100;b++){
      int ***cp=*(bp+n), c;
      for(c=0;c<100;c++){
        int **dp=*(cp+n), d;
        for(d=0;d<100;d++){
          n+=*(dp+n);
        }
      }
    }
  }
}
>>363
悪いけど、これを配列で表現してみてくれ。

(n+=*(dp+n); の型が不一致であることと、関数の戻り値が指定されていないことにはあえて触れないが。)
配列の方がポインタ読んで飛ばずに済むから早いのでは。
366デフォルトの名無しさん:04/03/09 22:22
>>365
分かってない
367名無し@沢村:04/03/09 23:09
>>360
>メモリに直接アクセスできるから、配列を使うより効率的なんだ。

ほう…配列は間接的にメモリにアクセスするのかい?
インデックス使うからレジスタ直じゃないってことでしょ

int型のポインタ、配列がそれぞれあるとして、

ポインタの場合
mov eax, dword ptr[edx] ; ポインタ参照
lea edx dword ptr[edx+4] ;ポインタ自身をインクリメント

配列の場合
mov eax, dword ptr[edx+ecx*4] ; 配列参照
inc ecx ;配列インデックスをインクリメント

見ての通り、ポインタにすると使用レジスタを減らせる
それこそ意味わかんね。
添え字変数の参照コストは比較しながら
ポインタ変数自体への参照コストは無視していいってのかね。

配列がスタック上なら
mov eax, [ebp-12+ecx*4]
で参照するが、staticな領域にあれば
mov eax, [_array+ecx*4]
となって、全然ポインタ参照
mov edx, [ebp-16] (ポインタ変数の参照)
mov eax, [edx+ecx*4]
または
mov eax, [_array]
mov eax, [eax+ecx*4]
と使用レジスタ数は変わらない。

eaxではなくecxなりをカウンタとして使うとしても
ポインタ変数がレジスタ変数になっているなら
 配列:ebpベース ポインタ:ebx(等)ベース  ・・・まったく同じ
レジスタではなく、スタック上に取られるなら
 配列:ebpベース ポインタ:edxなりにロードしてから再度参照
static領域
 配列:直接参照 ポインタ:edxなりに(ry
参照回数の問題じゃなくて、ヘボコンパイラだと添字分の足し算を
毎回するので遅くなる程度だ。
まともなコンパイラにちゃんと最適化させたら、たいてい差がなくなる。
だからヘボコンパイラだとポインタ変数の値を毎回読み出すから遅くなるんだろ?
372名無し@沢村:04/03/10 20:26
>>368
mov eax, dword ptr[edx] ; の場合、66 67 8B 02となってModR/Mバイトしか使わないが、
mov eax, dword [edx+ecx*4] ;の場合、66 67 8B 04 8Aとなるから、SIBバイトも使うってことか?
373一星 ◆Cppn/.YI3. :04/03/23 18:46
>>372
 出た!アセンブラの話になると元気になる機械語使い沢村。
俺がだいたい分かったこと

自作関数にはポインタは絶対に必要!
375デフォルトの名無しさん:04/04/18 10:15
例えば >1 ってのがポインタだな
>1 は1に書いてある内容を参照せよって意味だしな。
376デフォルトの名無しさん:04/04/18 13:36
ポインタは女の子のアドレスを保存するもの
377デフォルトの名無しさん:04/04/18 14:53
すいません初心者ですが1から376を読んでもさぱりわかりません
もっとわかりやすくお願いします。
要はポインタ渡しとアドレス渡しは一緒?
ポインタってのはそこの場所に この変数Aが常駐してますよ って事?
※だからそこの値を参照したり 値を変更したり出来る

アドレス渡しも一緒?
おんなじだよ。
379デフォルトの名無しさん:04/04/18 16:09
>>378
じゃあなぜ文言をわざわざ分けているのですか?
おにぎりとおむすびのようなもんだ
381デフォルトの名無しさん:04/04/18 16:18
>>377

女の子は実体
382デフォルトの名無しさん:04/04/18 16:24
>>381
それって実態が(このレスでいう女の子?)
アドレス渡しってこってすかい?
そこを参照すればいつでも女の子がいますよ みたいな
グローバル変数のアドレス   → 本妻
スタティック変数のアドレス  → 愛人
ローカル変数のアドレス    → 現地妻
アロケートした領域のアドレス → 売女
384デフォルトの名無しさん:04/04/18 16:34
>>382

ここでいうアドレスはあくまでも電話番号
あかん余計意味不になってきた
386デフォルトの名無しさん:04/04/18 16:38
>>383
アロケートしたらフリーしなさい

メンバ変数には電車で毎朝会う子か?
387デフォルトの名無しさん:04/04/18 17:09
newするタイミングは?
ムラムラしたとき
389デフォルトの名無しさん:04/04/18 17:15
>>387
一通りのエラーチェックのすんだ後
必要って時のギリギリのときにnewするのがよろし
390デフォルトの名無しさん:04/04/18 17:30
NULLチェック?
実はおまいらもポインタの意味わかってないと見た
ぬるボインだ
393デフォルトの名無しさん:04/04/18 21:05
ポインタのポインタのポインタ(3P)
ポインタへのポインタへのポインタ
395デフォルトの名無しさん:04/04/19 00:54
ポインタというか
間接アドレッシングがまともに装備されてないCPUがあることを初めて知った。
びっくらこいた。
396デフォルトの名無しさん:04/04/19 01:59
>>1
アドレスをかくのうしているはいれつのメモリのことですっ!!!!!11
>はいれつのメモリ

_| ̄|○
398デフォルトの名無しさん:04/04/19 02:39
メモリを指し示すものがポインタだ。それ以外の解釈なんてありえない。
399ダン:04/04/19 04:58
ウルトラ警備隊の専用車がポインタだ。それ以外の解釈なんてありえない。
オブジェクト相当のものを指し示すもののことだろ。
それがアドレスで実装されてるとは限らない。なんかのindexかもしれない。
メモリとも限らないかもしれない。
猟犬として改良されたものがポインターだ。愛玩犬としての解釈もあるかもしれない。
402Alto:04/04/19 10:57
マウスで動かす画面上の矢印がポインタだ。それ以外の解釈なんてありえない。
403デフォルトの名無しさん:04/04/19 11:56
>>400
はぁ?お前全く計算機のハードウェアがわかってないな。
オブジェクトはメモリ上にマッピングされなけりゃどこに
実装されるか考えてみろ。アホが
しかもindexとは何を意味してるんだ?それが物理的にどこに格納
されるか考えてみろ。
最後にスレタイよく読め。C++とは一言も書いてないだろうがバカ
>>400
C++で拡大解釈されたレジスタ変数へのポインタをありがたがってる
文法バカ -> ハードウェアのかけらも知らない糞
ポインタはあれだ
本のしおり
ポインタがなかったら世界のソフトウェア産業はここまで発展しなかった
>>404
お前はレジスタウィンドウや Mapped I/O すら知らないらしいな。
ぽいんたぁ
>>407
いや、>>403-404 は「オブジェクト」と聞くと「C++ かよ!」と思ってしまう
OOP 挫折組だろう。
おおきなオッパイがボインだ。おとうちゃんの為にあるんと違うんやで。
>>407
チッ!あのなぁ。レジスタウィンドウなどというのはレジスタをメモリ
代わりに使おうって発想なんだからメモリといっても差し支えないだろうが!
しかもMapped I/Dの前には Memoryの修飾詞がつくだろうが、少なくとも
コンパイラ側から見ればメモリと思ってアクセスしてる。だから
Memory Mapped I/Oなんだよ。

>>409
pure Cではレジスタへのポインタは許されてなかったという経緯も知らんのか?
アフォが!
ポインタが何か理解できたが、実際使うこと少ないな。
>>412 そんなことはない。
int x[100];
int i;
for(i = 0; i < 100; i++ ){
x[i] = i;
}

と書くより,
int *px;
px = x;
for( i = 100; i > 0; --i){
*px++ = i;
}
という風にポインタのインクリメント/デクリメントに持ち込むほうが一般的に
速い。
>>413
最近のPCでもそうなの?
415デフォルトの名無しさん:04/04/19 14:37
質問はageよな
>>411
で、C++ は何の関係があるんですか?
>>403
>しかもindexとは何を意味してるんだ?
例えば、非バイトマシンにおけるバイト位置とかじゃない?
>>414
最近では>>413の上のが速い
>>418
それは間違い。学生はスッコンデロ!コンパイルしてコード見ろ。
さらにカウントは0を終了条件にするほうが速いがこちらはどんな
オプティマイザでも一応対応してる。
レジスタの少ないCPUでレジスタ変数を指定することは逆に速度低下につながりかねないが
ポインタのインクリメントやデクリメントはCPUにハードウェアとして実装されてる機能であって、
これを下手にアドレッシング計算されると速度低下につながる。
まぁ、日英/英日翻訳がまともに機能するようになればコンパイラに頼り切ってもいいだろうけどね。
今の自動翻訳で意味わかるか?
421デフォルトの名無しさん:04/04/19 15:14
ちょっと難しいかな
422デフォルトの名無しさん:04/04/19 15:25
>>420
レジスタって何CPUって何変数って何インクリメントって何デクリメントって何
ハードウェアって何実装って何アドレッシング計算って何コンパイラって何?
>>420
>ポインタのインクリメントやデクリメントはCPUにハードウェアとして実装されてる機能であって
絶対だな?
PICにはないよ。てか、間接アドレッシング機能がそもそもない。
メモリもなくてデータ/プログラムともレジスタだけで動く。
>>419
お前は実際にコーディングして確かめたのか?
頼むから知識だけで物事を語るのはやめてくれよな。

ちなみに漏れの環境での結果は、(1000万回ループ)
>>413の上: 7937(ms)
>>413の下: 8078(ms)
まぁ大差はないがそういうこった。

漏れの環境がおかしいとか言われそうだなw
まぁ別にいいけど( ´ー`)y━〜~~
まあ >>413 みたいな細かい気配りが出来る人って



俺ゴリズムを駆使した挙句、猛烈に遅いコード書いたりするよね。
>>413程度のことを細かい気配りとか思っちゃってる香具師がいたのか。絶句。

あ、プログラマじゃないよね。じゃ仕方ないか。
>>413のプログラムは上と下で違うことをしてる
正しくは、
void funcA(){
int x[100];
int i;
for(i = 0; i < 100; i++ ){
x[i] = i;
}
}

void funcB()
{
int x[100];
int *px;

px = x+99;
for( int i =99; i>=0; --i){
*px-- = i;
}
}
429426:04/04/19 16:45
(´-`).。oO(なんで皮肉が通じないんだろ?)
gcc -O2 -march=pentium4 の結果は
funcA は
.align 2
.globl __Z5funcAv
.def__Z5funcAv;.scl2;.type32;.endef
__Z5funcAv:
pushl%ebp
xorl%eax, %eax
movl%esp, %ebp
subl$408, %esp
L6:
movl%eax, -408(%ebp,%eax,4)
addl$1, %eax
cmpl$99, %eax
jleL6
leave
ret
funcBは
.align 2
.globl __Z5funcBv
.def__Z5funcBv;.scl2;.type32;.endef
__Z5funcBv:
pushl%ebp
movl$99, %eax
movl%esp, %ebp
subl$408, %esp
leal-12(%ebp), %edx
L14:
movl%eax, (%edx)
subl$4, %edx
subl$1, %eax
jnsL14
leave
ret

ループ部分ではクロック数には差がないがループに入る前で1命令分だけ
funcAが少ないな。
>>425
お前いったいコンパイラに何使った?
次のプログラムで確認してみろ!

#include <iostream>
#define N 10000000
int x[N];

void funcA(){
int i;
for(i = 0; i < N; i++ ){
x[i] = i;
}
}

void funcB()
{
int i, *px;

px = x+N-1;
for( i =N-1; i>=0; --i){
*px-- = i;
}
}


int main()
{
funcA();
funcB();
}
gcc 3.3.1 コンパイラオプション -O2, gprof の結果は
index % time self children called name
<spontaneous>
[1] 100.0 0.00 0.09 main [1]
0.06 0.00 1/1 funcA() [2]
0.03 0.00 1/1 funcB() [3]
-----------------------------------------------
0.06 0.00 1/1 main [1]
[2] 66.7 0.06 0.00 1 funcA() [2]
-----------------------------------------------
0.03 0.00 1/1 main [1]
[3] 33.3 0.03 0.00 1 funcB() [3]
-----------------------------------------------
0.00 0.00 1/2 _GLOBAL__I_x [28]
0.00 0.00 1/2 _GLOBAL__D_x [25]
[6] 0.0 0.00 0.00 2 __static_initialization_and_destruction_0(int, int) [6]
-----------------------------------------------
つまりfuncAの方がfuncBより倍遅い。これでも上が速いというか?
この程度のプログラムで時間で計測しても誤差ばかりが目立つぞ。
>>433 == >>419 か?だとしたら学生じゃないんだな?

…恥の上塗りだな。
そんなもの、コンパイラにもプロセッサにも依存する。
つか、>>412 に対して >>413 のような例が出てくる辺りが
間抜けですね。
>>425
コンパイラの話をしてるのにコンパイラにもプロセサにも依存するのは当然だろうが。
86系でクロック数をカウントできるデバッガでも持ってりゃそれで示してやるがあいにく
持ち合わせてないんでな。
それともタイマ等もすべて止められるOSでポート叩いてロジアナでモニタすれば計測できるが
お前はそれやったのかい?
438437:04/04/19 18:11
>>425 訂正 -> >>435
439デフォルトの名無しさん:04/04/19 19:24
で、>>413に対しての回答は?
440デフォルトの名無しさん:04/04/19 19:24
すまん、>>414の間違いですた
gprofをつけると一部の最適化ができなくなったり
余計な命令が含まれてしまったりするのではないだろうか。
>>432の実行時間の測定が何の役に立つんだろう
メモリは国土
グローバル変数は世界遺産
ローカル変数は時価の高い土地
アロケート領域は借地
444デフォルトの名無しさん:04/04/19 22:09
今更の今更だけど、その程度のコードでは速度差なんてほとんどでないから、
理論的に計算して時間を求めたほうがいいよ。
たとえば1MIPSのコンピュータでどうとか。
速度はある程度遅い方が顕著になるともう
445田中康夫:04/04/19 22:12
アメリカのブッシュちゃんに「さーフセインちゃんをやっつけましょ〜」
って言われてイラクくんだりまで尻尾ふってついてく小泉ワンワンのことさー。
>>437
本っ当に頭悪いね…
>>432 のコードは、前者が速いこともあれば後者が速いこともある。
ふつーは後者が速い、なんてのは幻想。
>>446
お前アセンブリコードをまともに書いたことのない最低のド素人だな。
C書く前にCPUの構造を一から勉強しなおせ。
>>447は昨日入門書を見ながら摂氏⇔華氏変換プログラムを書いて感動しました。
ハ ー ド ウ ェ ア の か け ら も 知 ら な い 知 障 に ア セ ン ブ ラ は 無 理
必死だなw
>>447
アセンブリは死ぬほど書きました。
モノが ROM なのでハンドアセンブルも多かったですが。
趣味では CPU も TTL ランダムロジックで幾つか作りましたよ。
尤もそのマシンはパイプラインや先読みキャッシュ、分岐予測なんてのは
備えてませんので、あなたの思うような結果 (後者が速い) に
なるでしょうね。
>>446
>ふつーは後者が速い、なんてのは幻想。
それはお前のおつむが幻想見てるからだよ。配列のアドレッシングに出来るだけポインタの
インクリメント/デクリメントでアクセスできるようにデータをあらかじめ並べ替えて配置
するなどというのは常套手段。ループカウンタでお手軽にアクセスするのは
人間にはわかりやすくても機械にとっては負担が大きい。
私は>>446の意見に一票。
コンパイラによっても処理系によっても結果は違う、が厳密には正解だと思う。

だが、現実的にはこの程度のコードで差を生じさせるようなアホなコンパイラも
貧弱な処理系も稀な気がする。(組み込み系とかを除けば)
454453:04/04/20 12:43
あとついでに言っとくと、アセンブラがどうのこうのとか
(私に言わせると素っ頓狂なこと)言ってる人は、頭の中に昔の8ビットの
CPUとか想定してないか?
>>454
手元にLinuxかFreeBSDのソースコードあったら見てみな。カーネルだけでなく
ライブラリでもアセンブラで書かれてるものが結構あるから。Cのコード見てアセンブリ
結果を予測できないようじゃままごとアプリ書くのが関の山
>>455
数万行のCのコードを脳内アセンブルできないとダメですか。
>>456
>>455にとってはその程度朝飯前
(´-`).。oO(>>432で差が出るって言ってる人はx86しか知らないのかな)
68系、H8、あとほとんどのDSPでは明らかに差がでるな。むしろX86の方が差は出ない。
SPARC ではgcc -O3 で同じコード吐いた。
どうしても納得しない莫迦がいるようなので
VC++ 6.0 & Win2000 with PenIII 866MHz で実測。

さて、どうなるでしょう!?
(A) 意外と FuncA が速いんじゃない?
(B) FuncB が速いに決まってる!

  DWORD s[2];
  s[0] = GetTickCount(); funcA(); s[0] = GetTickCount() - s[0];
  s[1] = GetTickCount(); funcB(); s[1] = GetTickCount() - s[1];

  std::cout << "#" << i + 1 << ": " << s[i] << " [msec]" << std::endl;
  std::cout << "#" << i + 1 << ": " << s[i] << " [msec]" << std::endl;
#1: 351 [msec]
#2: 250 [msec]

次に、FuncA と FuncB の呼び出し順を入れ替えると
#1: 360 [msec]
#2: 251 [msec]

というわけで正解は、「(C) 最初に呼び出された関数が遅い」でした。
46256:04/04/20 14:31
同じコードは吐かんだろ?方やインクリメント方やデクリメント
それを同じコードはいちゃオプティマイズしすぎだと思うが?
あれ、間違えた。コードの最後の2行は

  for (int i=0; i<2; i++)
    std::cout << "#" << i + 1 << ": " << s[i] << " [msec]" << std::endl;

ね。
464460:04/04/20 15:51
>>462 たしかに完全に同じではないけど
# Cソースコード
int x[1024];
void funcA(void) { int i; for (i = 0; i < 1024; i++) x[i] = i; }
void funcB(void) { int i, *p; p = x + 1023; for (i = 1023; i >= 0; i--) *p-- = i
; }
int main(void) { funcA(); funcB(); return 0; }
# 以下、アセンブリ
funcA:
sethi %hi(x), %g2
or %g2, %lo(x), %g2
add %g2, 4092, %g2
mov 1023, %g3
.LL6:
st %g3, [%g2]
addcc %g3, -1, %g3
bpos .LL6
add %g2, -4, %g2
retl
funcB:
sethi %hi(x+4092), %g2
or %g2, %lo(x+4092), %g2
mov 1023, %g3
.LL12:
st %g3, [%g2]
addcc %g3, -1, %g3
bpos .LL12
add %g2, -4, %g2
retl
ループ部分は同じでしょ?
このコードの内容はどちらも内容的にfuncBにコンパイルされてるね。
カウンタは、はじめに1023がセットされて
addcc %g3, -1, %g3
でデクリメント。
ポインタも
sethi %hi(x+4092), %g2
で配列の末尾がレジスタg2に設定されて、
add %g2, -4, %g2
で4byteずつデクリメント。
ループ途中でiを引数にした関数でもコールすると違ってくるんだろな
funcAでは一度配列の先頭がg2にセットしてからわざわざ4092足して
末尾設定してることだけが違う。
467デフォルトの名無しさん:04/04/20 18:27
>>413 皿仕上ゲ
413のポインタの使い方おかしくね?あれじゃ遅いよ。
>>468
>413のポインタの使い方おかしくね?
どうおかしいの?
>>469
forのループでiのかわりにpxのポインタを使っていないとこ。
あーでもインクリメントしたiを入れたいのか。例が悪いな。
皿仕上げてるからマヌけなことかいてるのかと思えば、当たり前のこと書いてるだけジャン
2chには仕事でコンパイラ作ってる人もよく来るから、
生半可な知識を振り回すと恥をかくことが多い。
>>468 とか >>471 とか、バカ入れ食いだな。
いい加減、自分が一番バカなことに気づけよ -> >>473
>>471 メクラデスカ?
>>461 >>464
「far ポインタ」って何?
いわゆるx86系CPUの話だが。
16bitCPU時代は、アドレスも16bitで表現していた。最大アドレス値は高々64Kbyte。
しかしメモリがメガ単位まで増えると、64Kbyteを超えるアドレスにアクセスする必要
が出てきてしまった。
そこで、アドレスを上位と下位の二つに分割して、64Kbyte以内のメモリ単位(この範
囲をセグメントという)のプログラミングでは通常の16bitポインタを使い、セグメントを
越えるメモリ操作は、上記の上位アドレスを併用することで実現した。
このような拡張アドレスを操作するポインタを farポインタとよび、これに対して従来
の物をnearポインタと呼ぶ。
またfarポインタの上位アドレスは、セグメントの基点をあらわすことからセグメントア
ドレス、下位アドレスはセグメントを基点としたオフセット表現なので、オフセットアド
レスと呼ぶこともある。

現在ではCPUが32bitになり、アドレスバスも32bitに増えた。このため表現できるア
ドレス空間も4Gまで増えたため、farポインタを使う必要性はほとんどなくなっている。
478デフォルトの名無しさん:04/05/11 22:33
ポインタがないと困る点を5個述べよ。
479デフォルトの名無しさん:04/05/11 22:54
モジュールの使い回しができない。
480デフォルトの名無しさん:04/05/11 22:55
ポインタを使ったソースコードがコンパイルできなくなる。
char**と*chat[]って何が違うのよ?
>>481
文脈によってはまったく同じ
リスト構造の実装が困難
ツリー構造の実装が困難
スタックの実装が困難
キューの実装が困難
>>483
全て参照を使うことでもっと簡単に安全に実装できますね。
ポインタのポインタはポポインタ
>>485
あ!
487おでん:04/05/12 02:02
>>432 の実行結果ですが・・・

LccWinだと、こうなりました。
(W2K+sp4 P3-650*2)
Wedit profiler.
Command: "e:\lcc\hello.exe "
Generated 2004.5.12.1.49.26
_funcA | 123| 0| 55.16 hello.obj
_funcB | 100| 0| 44.84 hello.obj
_main | 0| 223| 0.00 hello.obj

Total profiler stops: 239
Total direct module hits: 223

Wedit profiler.
Command: "e:\lcc\hello.exe "
Generated 2004.5.12.1.54.25
_funcB | 122| 0| 55.71 hello.obj
_funcA | 97| 0| 44.29 hello.obj
_main | 0| 219| 0.00 hello.obj

Total profiler stops: 236
Total direct module hits: 219

やっぱり、先に呼ばれたほうが遅いですね?
488デフォルトの名無しさん:04/05/12 04:13
test
>>484
>>483の例はすべてクラスのメンバに他(or 自分)のクラスのポインタを含む場合だが。参照でどうやって書くの?
>>484
gccのbits/list.tccではポインタ使って書いてる。
ポポイのポポイのポポイのポイ
ポポインタ
知ってるとプログラムが書きやすくなる。
493デフォルトの名無しさん:04/05/12 19:23
p-
494名無し@沢村:04/05/12 19:47
>>1
本に書いてあるよ、本読めよ。
幼稚園かおまえ?
ポインタン
496デフォルトの名無しさん:04/05/12 21:18
>>455
それはハードを操作するからじゃないのかね。
ブートローダとか、HDDの操作とか。
スピードのためにアセンブリ使っているわけでないような気がするが。
497デフォルトの名無しさん:04/05/12 21:29
ってか413のプログラムって、Windowsで実行するのと、Linuxで実行するのでは、
計測結果が激しく違う予感がするぞぉ。
プロセスの管理方法とかが一緒なの毛?

やるならブートローダーにそのプログラムを直に書いて、FDDでブートさせて計測したほうがよさそうな予感。

ってかそこまでやっても何も得られん・・・ゲハ
498デフォルトの名無しさん:04/05/12 23:24
ポポインタのポポインタはタンポポ
499デフォルトの名無しさん:04/05/12 23:35
ウィンドウズアプリなんかじゃ、スタック使うときだけポインタを使えばいいのか。
あとは参照にすべしで決まりだ。
>>496
strcpy() とかのソース見れ。
いくつかのプロセサは、文字列操作に特化した命令を持ってるから、そういうのを使うためにアセンブラで書くのは珍しくない。
>あとは参照にすべしで決まりだ。
参照なんてなもんはなくても構わない。
宣言時、初期化できない/したくないときは参照はつかえない。
504デフォルトの名無しさん:04/05/21 00:18
age
505佐々木洋子:04/07/13 18:45
インポと名前が似ていて、聞いていて恥ずかしいですね(笑
506デフォルトの名無しさん:04/09/30 03:34:08
>>495>>498
上級者に、初心者はポインタの意味だけでつまずいてるわけじゃないことを
理解させることは容易じゃないようだ
507デフォルトの名無しさん:04/09/30 03:57:57
メモリっていうのはビット列とそのビット列が入っているところをあらわす
アドレスがあります。
たとえば、下の図がわかりやすいと思います。
左側にあるのがアドレスで囲ってあるところが中に入っているビット列が
意味する数字です。
  +---+
  100 |10 |
  +---+
  101 |10 |
  +---+
  102 | 0 |
  +---+
  103 | 9 |
  +---+
  |20 |
  +---+

int *a, *b;
*a = 10;
b=a;
aはアドレスをあらわし、*aは中には言っているビット列をあらわします。
たとえば、メモリが上の図の通りになっているとすると、
aに100が入っていると、*aは10(この場合はint型だから数字だけど)
をあらわすことになります。
ポインタとはメモリのアドレスを指し示すそのままの意味の「ポインタ」
なのです。メモリ上のビット列をアドレスでポイントしているのです。
では、b=aは何を意味しているのかというと、bにaのアドレスをコピー
しているのです。
つまり、bには100が入って、aと同じ10という数字を示すことになります。
508r ◆r/etvCKR2A :04/10/23 15:48:27
>>503
出来るだけそういう風に書かないでもいいようにコーディングしたい
509デフォルトの名無しさん:04/10/31 21:48:11
メモリの事を丁寧に説明してからポインタに移るのが良し
510デフォルトの名無しさん:04/11/07 18:39:54
自分が昔ポインタ理解できたきっかけは
どこのアドレス指してるとかの説明よりも
ディレクトリでかも知れんなぁ
511デフォルトの名無しさん:04/11/20 06:47:56
512デフォルトの名無しさん:04/11/20 13:15:42
**************** 糸冬 了 ****************
513デフォルトの名無しさん:04/11/22 10:37:18
514デフォルトの名無しさん:04/11/22 13:39:01
>>507
へったくそな説明やなぁ〜
515デフォルトの名無しさん:04/11/23 00:09:54
>>514
上手な説明をどうぞ。逃げないでちゃんと解説よろ。
516デフォルトの名無しさん:04/12/01 21:07:53
中途半端にハードウェアの初歩的知識がある人には
「ポインタ」の箇所を「アドレス変数」って読み替えるといいよ、って言ってる。
517デフォルトの名無しさん:04/12/01 21:19:24
int* a なら
「int型のアドレスを指す変数」

大体理解できるんじゃないか?
518デフォルトの名無しさん:04/12/01 21:20:44
ファイルから文字列を読み込もうとしているのですが、
txtなら1行づつ読み取れるのですがexcelの場合は、そうもいかないみたいでして
excelの場合の読み取りの仕方を教えてください。
以下に僕が作ったサンプルプログラムを書きます。
br = new BufferedReader (
new InputStreamReader (
new FileInputStream( "SJISin1.txt" ), "SJIS" ) );

while( ( str = br.readLine() ) != null ) {
System.out.println( str );
}
というような感じです。宜しくお願いします。
なお部分的に抽出する場合も教えていただけるとうれしいです。
例えば3行2列目の文字列を読み取るなどです。
519デフォルトの名無しさん:04/12/02 00:59:16
csvじゃなくてxlsを読もうとしてる?
520デフォルトの名無しさん:04/12/02 06:40:37
つーかマルチ臭がする上にスレ違い
521デフォルトの名無しさん:04/12/02 18:50:52
元々過疎スレなんだし、スレのネタすら無くて終わってるんだから、
まったりと教えてやれよ。
522デフォルトの名無しさん:05/01/07 15:15:54
2
523デフォルトの名無しさん:05/01/07 15:16:17
22
524522,523:05/01/07 15:23:58
上げてしもた…申し訳ないorz
525デフォルトの名無しさん:05/01/07 15:40:11
ぽいんとあああああああああ
526デフォルトの名無しさん:05/02/15 04:18:17
C言語のポインタは「指し示すもの」です。
527デフォルトの名無しさん:05/02/15 15:04:21
マウスカーソルのポインタも「指し示すもの」です。
528527:05/02/15 15:04:48
マウスカーソルのポインタて…orz
529デフォルトの名無しさん:05/02/28 17:47:18
char *aに配列へのポインタを格納した場合配列の長さはわからない?
530デフォルトの名無しさん:2005/04/27(水) 16:28:58
int main()
{
int a = 1000;
int *p;
int **pp;

p = &a;
pp = &p;
printf("%d\n",**pp);

return 0;
}
この場合、
a … 1000
p … aのアドレスを指す
&p … pのアドレスを指す
*p … pが指しているアドレスの値、1000を指す
pp … pのアドレスを指す(つまり&p)
*pp … pが指しているアドレスを指す(つまりp)
**pp … pが指しているアドレスの値、1000を指す
という解釈で合ってますでしょうか。
531デフォルトの名無しさん:2005/04/28(木) 13:33:39
>>530
あってるよ
532デフォルトの名無しさん:2005/04/28(木) 14:50:37
>>530
「ポインタ値=アドレス値」とは限らない。
「ポインタ値=オブジェクトを指し示す値」だ。
環境によってはアドレス値であるかもしれないし、
オフセットアドレスであるかもしれない。
533デフォルトの名無しさん:2005/04/29(金) 08:29:58
関数名もポインタ?
534デフォルトの名無しさん:2005/04/29(金) 11:38:59
「アドレスを指す」んじゃなくて「オブジェクトを指す」or「アドレス値を持つ」
535デフォルトの名無しさん:2005/04/29(金) 14:37:27
あーわかんね
もうポインタの本を何冊買ったか覚えてねえ
タンスとかの図を載せてるけど
コンピュータの中にタンスが入るわけねえだろとか
余計なことばっかり気になってしまう
これはもう、能力とかじゃなくて相性だな
536デフォルトの名無しさん:2005/04/29(金) 15:26:38
俺が初めてBASIC触ったときの説明書で(カシオのPB100)、
変数とか配列とかを箱が並んでる絵で説明してて、わけわからんかったな

それはともかく、Cのポインタは便利すぎるのか、素人が苦し紛れに
使って、わかりづらいコードになること多い。配列使え
537デフォルトの名無しさん:2005/04/29(金) 16:29:14
>>535
能力だと思う。
538デフォルトの名無しさん:2005/04/29(金) 18:20:24
実はCでもJavaみたいにポインタを使わずに済む
コーディング方法ってあるんだろ?
実行ファイルのパフォーマンスは最高なんだから
あとはポインタさえなけりゃ最強の言語なんだよ
なっ教えてくれよ
539デフォルトの名無しさん:2005/04/29(金) 18:52:56
>>535
クロヌ
「ポインタの本」なんつーターゲット絞り込みすぎ気味の本なんてあるのか?
540デフォルトの名無しさん:2005/04/29(金) 18:54:02
結構たくさんあるよ
541デフォルトの名無しさん:2005/04/29(金) 18:54:16
>>538
ポインタ使わなきゃ関数にヒキ渡せないものばっかりジャン
542デフォルトの名無しさん:2005/04/29(金) 19:25:11
そうなんだクロテゴメソ
543デフォルトの名無しさん:2005/04/29(金) 19:49:55
難しいとは知ってたが見事にポインタでつまずいた。
いま「ポインタが理解できない理由」読んでるけど、
こんなんを初めてでも簡単に理解できる人は凄いよ。
Cの勉強し始めて「頭良い・悪い」が何なのか分かった気がする。
544デフォルトの名無しさん:2005/04/29(金) 20:44:17
>>543
そういう本もある意味変だよな。
わからない理由がわかってたら
それはわかってるということだからな。
545デフォルトの名無しさん:2005/04/29(金) 20:58:16
なんか自分で考える代わりに本を読むだけの人増えてる?
546デフォルトの名無しさん:2005/04/29(金) 23:18:24
ハード的なメモリの構造について勉強したことがない?機械語で遊んだことがない?
547デフォルトの名無しさん:2005/04/30(土) 08:50:54
win環境なら、VBとJavaとかから入るだろうから
メモリ構造理解するとかしないでしょ
548デフォルトの名無しさん:2005/04/30(土) 09:45:29
メモリ構造なんていうたいそうなもんでもないけどな。知るべきことは。
DOSのころは、セグメントだのバンクだのっていう瑣末なことまで気にしていたが、
今となっちゃただ単にリニアなアドレスを持つ仮想のメモリ空間を相手にするだけだ。
だから、そこじゃないんだろ難しいのは。

例のポインタに関するCの変てな表記法や文化が混乱の元。
関数ポインタとか、配列とポインタの混同とかさ。

ポインタ変数の、組み込み型変数としての普遍性と特殊性を押さえないとな。
549デフォルトの名無しさん:2005/04/30(土) 09:56:16
メモリのアドレスを入れる変数=ポインタだと思ってるのだが違うのか?
550デフォルトの名無しさん:2005/04/30(土) 10:22:40
まぁ、そんなところだ
551デフォルトの名無しさん:2005/04/30(土) 10:31:04
で、分かんないのが関数ポインターってドウ使うの?
Win32SDKで使ってたようなきがするんだけど、いまいち実感が無くて。
誰かおしえぇて。
552デフォルトの名無しさん:2005/04/30(土) 10:44:22
>>551
関数を変数に入れたいときに使う。
変数に入れられれば、関数の引数として渡せるようにもなる。
553デフォルトの名無しさん:2005/04/30(土) 10:55:09
配列にして番号で関数指定できるとか
554デフォルトの名無しさん:2005/04/30(土) 10:57:30
>>551
REGISTERCLASSEX、CreateWindow、CreateDialog
555デフォルトの名無しさん:2005/04/30(土) 11:08:09
単純な例ですが
#include <stdio.h>

typedef void(*FUNCPTRDEF)(int index);

void FuncNPE(int index)
{
  printf("ぬるぽ%d\n",index);
}

void FuncGa(int index)
{
  printf("ガッ%d\n",index);  
}

void FuncCall(FUNCPTRDEF func)
{
  int i;
  for(i=0;i<10;++i){
    func(i);
  }
}

int main()
{
  FuncCall(FuncNPE);
  FuncCall(FuncGa);
  return 0;
}
556デフォルトの名無しさん:2005/04/30(土) 11:11:55
さりげなくぬるぽってるのが最高
557デフォルトの名無しさん:2005/04/30(土) 11:24:43
                Λ_Λ   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
                (・∀・ )< HSPで大金持ちになるんだ。
             _φ___⊂)__ \_______________
           /旦/三/ /|
        | ̄ ̄ ̄ ̄ ̄|  |
        |        |/
558デフォルトの名無しさん:2005/04/30(土) 12:50:11
&と*が分かりにくい?
しかしそういわれてモナー

size ofみたいにaddress of演算子とかその逆のcontent of演算子とかにする?
長々しくなってヤダー
559デフォルトの名無しさん:2005/04/30(土) 18:37:12
#define ADDRESSOF(v) (&(v))
560デフォルトの名無しさん:2005/04/30(土) 20:05:45
文字列定数はポインタである、ってことがどうしても解りません。
教えてください。
561デフォルトの名無しさん:2005/04/30(土) 20:35:45
>>560
ヒント:文字列定数が格納されているところのポインタ
562デフォルトの名無しさん:2005/04/30(土) 20:52:35
voidへのポインタの配列へのポインタを引数にしてvoidへのポインタを返す関数へのポインタの配列を定義したい
563デフォルトの名無しさん:2005/04/30(土) 21:19:26
さようなら
564デフォルトの名無しさん:2005/04/30(土) 21:44:38
ボンジュ〜ル
565デフォルトの名無しさん:2005/04/30(土) 21:57:44
typedef void *(*FUNC[])(void *(*)[]);
566デフォルトの名無しさん:2005/04/30(土) 21:59:50
>>560
文字列定数はポインタじゃないよ。
567デフォルトの名無しさん:2005/04/30(土) 22:04:41
>>565
うひょ〜
てゆーか
うげ〜
568デフォルトの名無しさん:2005/04/30(土) 22:07:56
typedef void *PVOID;
typedef PVOID APVOID[];
typedef PVOID FUNC(APVOID *);
typedef FUNC *PFUNC;
typedef PFUNC APFUNC[];
569デフォルトの名無しさん:2005/04/30(土) 22:12:08
C言語って基地外だな。
*(*)[] ってばかじゃねーの?
570デフォルトの名無しさん:2005/04/30(土) 22:15:50
上の方で紹介されてる「ポインタの本」ってこういう問題ばっかりガンガン載ってるのかな?
571デフォルトの名無しさん:2005/04/30(土) 22:20:47
こんな問題は数をこなすより、個々の要素をちゃんと押さえるほうが大事。

・関数ポインタ と その配列。
・配列へのポインタ
・引数と返り値では、仮引数名が省略される。

この3つを押さえれば、どんな複雑な型でも書ける。
572デフォルトの名無しさん:2005/04/30(土) 22:25:45
そもそもtypedefを使えばどんな複雑な型でも書ける。
573デフォルトの名無しさん:2005/04/30(土) 22:27:01
char* szA = "1234568790";
char szB[] = "1234568790";
これの違いを適切に言えるなら初心者脱出。
574デフォルトの名無しさん:2005/04/30(土) 22:30:19
>>571
導師よ!
575デフォルトの名無しさん:2005/04/30(土) 22:57:55
実用レベルでは、「配列へのポインタ」ってほとんど使われない。
配列先頭要素へのポインタで事足りる。
576デフォルトの名無しさん:2005/04/30(土) 23:09:20
>>575
2次元配列へのポインタをしまうときに使う。

int aa[2][2], a[2];
int (*pa)[2];
pa = &a
pa = aa;
577デフォルトの名無しさん:2005/04/30(土) 23:44:22
ポインタって必要なの?
アドレス参照したいなら&でいいんじゃないの?
578デフォルトの名無しさん:2005/04/30(土) 23:46:50
>>577
なくても、プログラミング出来なくはない。
でもめんどくさいよ。
579デフォルトの名無しさん:2005/05/01(日) 00:05:53
>>573

> char* szA = "1234568790";

char型のデータを格納するメモリのアドレスを格納するための
変数「szA」を定義し、文字列データ"1234568790"の格納されている
メモリの先頭アドレスを格納する。

> char szB[] = "1234568790";
char型の配列変数「szB」を定義し、文字列データ"1234568790"を
構成する各文字コードデータをszB[0]から順に格納する。

…これで合ってますかね
580デフォルトの名無しさん:2005/05/01(日) 01:16:19
>>577
intのポインタとか便利じゃね?
アドレスだと、インクリするときにa=a+sizeof(int); とか面倒じゃね?
ポインタならa++;で済むからテララクスwwwwwうぇwww
581デフォルトの名無しさん:2005/05/01(日) 06:18:26
>>577
おまいは全ての関数を値渡しで作るのか?
582デフォルトの名無しさん:2005/05/01(日) 10:46:33
ポインタだって値渡しだ。

例えポインタがなくても、アドレスをintかlongにキャストして渡せば、同じことが出来る。
手間はかかるが。
583デフォルトの名無しさん:2005/05/01(日) 15:36:46
環境によってはintで死ねる
584デフォルトの名無しさん:2005/05/01(日) 19:18:17
なんか本末転倒なような
アドレスを扱うんならポインタがあった方がいいでしょ
アセンブラじゃないんだし抽象化もされてるし
アドレスを扱わない言語仕様ならポインタも不用だけど
配列も関数も渡すのが難しくなる
585デフォルトの名無しさん:2005/05/01(日) 20:25:54
586デフォルトの名無しさん:2005/05/01(日) 20:30:10
>>583
環境によってはlongでも死ねる。
587デフォルトの名無しさん:2005/05/01(日) 20:33:32
>>582
阿呆だ・・・
588デフォルトの名無しさん:2005/05/01(日) 23:20:35
別に阿呆じゃあないと思うよ
視点を変えて説明しようとしたんだろう
詰めが甘かったけど
589デフォルトの名無しさん:2005/05/02(月) 12:32:00
ポインタ値をスカラ型にキャストするほど危険な事もないね。
590デフォルトの名無しさん:2005/05/02(月) 12:40:56
んなこたない
591デフォルトの名無しさん:2005/05/03(火) 19:54:05
ポインタを使わなければ、実現できないプログラムってあるんですか?
592デフォルトの名無しさん:2005/05/03(火) 20:02:50
>>591
int main(int argc, char** argv)
593デフォルトの名無しさん:2005/05/03(火) 20:05:26
Cに限ればいくらでも出てきそうだな
594デフォルトの名無しさん:2005/05/03(火) 20:31:18
>>592
では、具体的にどういう時に使えば便利(に、プログラムが組める)でしょうか?

595デフォルトの名無しさん:2005/05/03(火) 20:39:57
>>594
添え字無しで配列が扱えるところ。
えーと、たとえば
forで回してるときは愛があるから配列で・・・
whileで回しているときは愛がないからポインタで・・・
596デフォルトの名無しさん:2005/05/03(火) 20:53:55
>>592
俺はこの「char **argv」でCに挫折した。
これは初心者に対するイジメだ。
597デフォルトの名無しさん:2005/05/03(火) 21:08:45
>>595
なるほど、そうですか
あんまり、whileを使ったことがなかったですので
新鮮です。
598デフォルトの名無しさん:2005/05/03(火) 21:10:56
while + ポインタ を研究してみたいと思います。
ありがとうございました
599デフォルトの名無しさん:2005/05/03(火) 22:36:57
HSPからCに移行した時にポインタやアドレスを知って
今まで疑問だった部分があっさり氷解した覚えがあるなぁ
あれは感動ものだった…
今ではポインタ無しとか不自由でしょうがない
600デフォルトの名無しさん:2005/05/04(水) 19:25:45
char *
が文字列だってことさえ理解したら
char **
問題ないでしょ?
601デフォルトの名無しさん:2005/05/04(水) 19:49:22
問題なく理解できる人も居れば拒否反応見せる人もいるんだなぁ世の中には
602デフォルトの名無しさん:2005/05/04(水) 20:42:20
typedef char * LPCHAR;
typedef char ** LPLPCHAR;

と定義すれば分かりやすい。
603デフォルトの名無しさん:2005/05/04(水) 20:44:35
むしろ

typedef char* PCHAR
typedef PCHAR* PPCHAR
604デフォルトの名無しさん:2005/05/04(水) 20:48:13
あ、そうね。
605デフォルトの名無しさん:2005/05/04(水) 21:33:28
typedef char * String;

のがいいんじゃない?
606デフォルトの名無しさん:2005/05/04(水) 21:36:21
名前は好きにすればいい
607デフォルトの名無しさん:2005/05/04(水) 22:28:08
どっちみちいつかはchar *を明かさなければならないときがくる。
608デフォルトの名無しさん:2005/05/04(水) 23:39:38
>>600
char *が文字列のアドレスを持つ変数の宣言ということはわかる。
しかしchar **が何を意味するのかいくら考えてもわからない。
文字列のアドレスを持つ変数のアドレスを持つ変数宣言?
そうやっているうちにウッキーとなって本を投げて布団かぶって寝る。
609デフォルトの名無しさん:2005/05/05(木) 03:23:52
言語で理解すんなよ。
610デフォルトの名無しさん:2005/05/05(木) 09:04:11
関数の仮引数ならとりあえずchar *argv[]と書いて「ポインタの配列」と話を進められるが……。
611デフォルトの名無しさん:2005/05/05(木) 11:46:18
>608
ま、こういうのは例を考えるのが一番

func1(){
char** array_str={
"ぬるぽ",
"ガッ"
};
 func2(array_str);
}

func2(char** strings){
printf(*strings); //ぬるぽと表示
*strings++;      //次の文字列に変更
printf(*strings);   //ガッと表示
}
とすると
func2では、
*stringsでは、呼び出し元の文字列配列の書く文字列を指す。
**stringsでは、各文字をさす
612デフォルトの名無しさん:2005/05/05(木) 16:09:52
>>611
例示ありがとう。
でも、んーわからん。
*が二つ以上付くとどういう機能を果たすのか
この根本原理がわからない。
文字列のアドレスを二つ別々に持てる変数…?

*stringsが各文字列を指して
**stringsが各文字を指す…???まるで魔法だ。
やっぱり自分には無理と思う。スレ汚しすまん。
それではさらばっ
613デフォルトの名無しさん:2005/05/05(木) 16:11:28
図を書けばすぐわかると思うんだが。
614デフォルトの名無しさん:2005/05/05(木) 16:16:15
>どういう機能

機能とか考えてる時点でだめだなw

** でポインタのポインタ
"〜のポインタ"ってだけ
615デフォルトの名無しさん:2005/05/05(木) 18:59:38
文字列って普通に使うものなのんだけど、Cで直接表現できないのが
初心者の混乱の原因なんだろうね。あと、ポインタと配列を意図的に混合してるのが
紛らわしいのかも。

・Cの文字列の実体は char の配列なんだけど、
 簡単に先頭要素のアドレスで表すことが多い (char *)
 これが重要

・文字列の配列は、char ary[10][20] とか2次元配列で表現してもいいんだけど
 普通は、実体はどっかに作っておいて、先頭要素アドレスの配列であらわす(char *ary[10])

で、main の引数みたいに、「文字列の配列」を他の関数に渡すときの、
呼ばれる側の関数の仮引数は、この場合 char *ary[10] または char **ary となる
616デフォルトの名無しさん:2005/05/05(木) 19:00:04
思ったんだけど、ポインタの 『 * 』 が 『 演算子 』 だと気付いていない人が結構居そうな気がする
あと、配列の 『 [] 』 も (ry
617デフォルトの名無しさん:2005/05/05(木) 19:11:20
変数宣言(仮引数)のときは「演算」してないから、それを言っても・・
618デフォルトの名無しさん:2005/05/05(木) 19:18:41
だからC++では「char*」で一つの型として記述しようとしてるんかの
619デフォルトの名無しさん:2005/05/05(木) 19:21:33
大人しくStringにすればいいのに。
620デフォルトの名無しさん:2005/05/05(木) 20:08:58
>>611
char *array_str[]じゃないと駄目だろ。
621デフォルトの名無しさん:2005/05/05(木) 21:36:47
Stringを使え
622デフォルトの名無しさん:2005/05/05(木) 21:53:34
おとなしくC++使えばいいのに。
623デフォルトの名無しさん:2005/05/06(金) 01:49:46
char c;  // c は char型
char *p;  // *p は char型
char **pp; // **p は char型
char f(); // f() は char型


簡単だろ。
624デフォルトの名無しさん:2005/05/06(金) 02:21:56
プ
625デフォルトの名無しさん:2005/05/06(金) 02:32:34
>>624
626デフォルトの名無しさん:2005/05/06(金) 02:53:00
プインタ
627デフォルトの名無しさん:2005/05/06(金) 07:16:47
やったことはないけど、

char a;
char ***b=&(&(&a));
みたいな書き方で良いの?なんかキモチワルイ。
628デフォルトの名無しさん:2005/05/06(金) 09:46:49
>>627
そうはできない。
char c;
char *pc = &c;
char **ppc = &pc;
char ***pppc = &ppc;

typedef char SZ[4];
SZ sz;
SZ *psz = &sz;
SZ **ppsz = &sz
上のコード片をtypedefを使わないで書くと下のようになる。
char sz2[4];
char (*psz2)[4] = &sz2;
char (**ppsz2)[4] = &psz2;

そして配列から先頭要素を指すポインタへの読み替えでこんなことができる。
char *p2 = sz
char *p3 = sz2;
SZ hoge[8];
SZ *phoge = hoge;
char hoge2[8][4];
char (*psz3)[4] = hoge2;

こんなんだから混乱するんだよな。
629デフォルトの名無しさん:2005/05/06(金) 19:35:37
&a = &b;
とかは?
630デフォルトの名無しさん:2005/05/06(金) 20:46:58
>>26

この連休にようやく仕様変更が行われますた。
しかしポインタで宣言した変数には既に前に値が入っていた模様
631デフォルトの名無しさん:2005/05/06(金) 22:08:56
非処女 = クズ
デカチチ = ゴミ
チャパツ = カス
短スカート = アホ
632デフォルトの名無しさん:2005/05/06(金) 22:10:06
>>629
&演算子の結果は左辺値ではないので = の左辺には置けない。エラーになる。

ただし大穴としてC++でaが何らかの(非constな)参照型を返すoperaotr &()をオーバーロードしているオブジェクトで、
&bの結果がその何らかの型へ変換できる場合はもちろんコンパイルは通る。
633デフォルトの名無しさん:2005/05/06(金) 23:14:08
&a = &b;
と同じことができる言語もあるのにね
634デフォルトの名無しさん:2005/05/07(土) 12:55:19
>>629
&a = &b;
なんて真顔で書いてる奴見つけたら、キーボードで殴る
635デフォルトの名無しさん:2005/05/07(土) 14:26:46
建設作業員の俺から言ってみれば
おまえら何しゃべってるのか意味がわからん
たのしいけえ?
636デフォルトの名無しさん:2005/05/07(土) 14:53:52
建設作業員の僕でも楽しいです。
637デフォルトの名無しさん:2005/05/07(土) 15:09:16
みなさん、最高ですか?
638デフォルトの名無しさん:2005/05/07(土) 15:45:29
全てはいい加減な言語設計をした作者が悪い。
C作ったの誰だゴルァ
639デフォルトの名無しさん:2005/05/07(土) 16:20:25
char a;
char **b;
char *A=&a,*B=*b;
640デフォルトの名無しさん:2005/05/07(土) 16:26:56
>>638
文句あるなら自分で言語作れ。D言語みたいなのは無しの方向で
641デフォルトの名無しさん:2005/05/07(土) 16:41:09
K&R読んで、C言語のポインターの仕様がスッと頭に入らなかった
敗残者のスレはここかよ、おぃ(獏称
642デフォルトの名無しさん:2005/05/07(土) 16:51:19
*がアドレス **がアドレスのアドレス
643デフォルトの名無しさん:2005/05/07(土) 16:52:02
ぬるぽを呼び出す方法。
((void (*)())0)();
644デフォルトの名無しさん:2005/05/07(土) 16:53:45
24 名前: ウンコ [sage] 投稿日: 2005/05/07(土) 13:51:53
/** Sample.c
*  コンパイル方法:
*      gcc -E Sample.c | sed -e 's!&\*!!g' > Sample.i.c
*                          ~~~~~~~~~~~~~~~~~外部プリプロセス処理
*      gcc -o Sample.exe Sample.i.c
*/
#include <stdio.h>
#define S(v)    &v
// 下記置換はC pre processorでは不可能なので、外部プリプロセスで処理する
//#define &*

int main(int argc, char*argv[], char*envp) {
  int v = 1;    // intの変数宣言
  int *P;       // intへのポインタ変数宣言
  P = &v;       // intのポインタ変数へ、intの変数のアドレスを代入
#define p  *P
  //S(p);       // intの変数へのポインタ
  //p;          // intの値

  int n = 2;    // intの変数宣言
  //n;          // intの値
  //S(n);       // intの変数へのポインタ

  S(p) = S(n);  // intのポインタ変数に、intの変数のアドレスを代入
                // 外部プリプロセス処理の結果、
                // &*P = &n は P = &n と同じ
  p = n ;       // intの値の代入
                // *P = n つまり v = n と同じ
  return 0;
}
645デフォルトの名無しさん:2005/05/07(土) 19:33:34
>>642
アドレスのアドレスってのが
どういう意味なのかさっぱりわからん。
ちょうど三次元の世界に住む俺らが
四次元の世界をイメージするようなもんか。
メモリのアドレスはアドレス一つで一意に決まるんだから
ポインタは*一つの使用法以外にないと思うのだが。
646デフォルトの名無しさん:2005/05/07(土) 19:47:47
関数の中で引数で渡されたポインタの中身を変えたい時はどうすんのさ
*aで受けてa = bとかしても変わらんから
**aで受けて*a = bとかするだろー
そんな複雑なもんじゃないよ
647デフォルトの名無しさん:2005/05/07(土) 20:02:50
>>645
『アドレスを格納する変数』 のアドレス
648デフォルトの名無しさん:2005/05/07(土) 20:41:03
>645
なんか、混乱してるようだけど
そんなに難しいもんじゃないよ。

普通のポインタは
int *p
int i
p=&i
なら
ポインタ変数(p) → ポインタにさされる変数(i)

っていう風にさしてるよね?

int **q
int *p
int i
p=&p
q=&p
なら

q → p → i

っていう風にポインタがさしてるだけ。

ただ単に、→が1つ伸びただけ。
649デフォルトの名無しさん:2005/05/07(土) 20:51:09
そこで、UMLのcollaboration図、Lispのセル図が、大活躍するですよ!!!
650デフォルトの名無しさん:2005/05/07(土) 20:56:35
>>649
ねーよw
651デフォルトの名無しさん:2005/05/07(土) 21:56:37
>>645
そもそも642の説明が間違っている。

変数宣言時はこんな意味になる。
* ポインタ変数。(変数のアドレスを格納する変数)
** ポインタへのポインタ変数。(ポインタ変数のアドレスを格納する変数)

どっちも変数のアドレスを格納すると言う点においては何ら変わりない。
652デフォルトの名無しさん:2005/05/07(土) 22:54:04
機械語知ってれば間接参照なんてフツーに理解だけどね
653デフォルトの名無しさん:2005/05/07(土) 23:16:29
16進数の羅列をみて何を理解汁と?
654デフォルトの名無しさん:2005/05/07(土) 23:23:22
>機械語

正確にいうと機械語ではなくアセンブラだろ?
655デフォルトの名無しさん:2005/05/07(土) 23:28:32
int *p;
てのは p がintポインタ型という宣言じゃなくて
*p が int型という宣言だろ。

C++ とかでよくやる
int* p;
て宣言は激しくキモいんだが。
656デフォルトの名無しさん:2005/05/07(土) 23:32:42
だからポインタ型という型概念を作ってるんだろ、C++は

>>655自身がキモイ
657デフォルトの名無しさん:2005/05/07(土) 23:39:01
>>654
>ら?
アセンブラ
アセンブリ
アセンブル
アセンブレ
アセンブロ
658デフォルトの名無しさん:2005/05/07(土) 23:39:25
アセンブリ茶
659デフォルトの名無しさん:2005/05/07(土) 23:43:58
そりゃセンブリ
660658:2005/05/07(土) 23:45:53
         ナ ゝ   ナ ゝ /    十_"    ー;=‐         |! |!   
          cト    cト /^、_ノ  | 、.__ つ  (.__    ̄ ̄ ̄ ̄   ・ ・   
                                             
            ,. -─- 、._               ,. -─v─- 、._     _
            ,. ‐'´      `‐、        __, ‐'´           ヽ, ‐''´~   `´ ̄`‐、
       /           ヽ、_/)ノ   ≦         ヽ‐'´            `‐、
      /     / ̄~`'''‐- 、.._   ノ   ≦         ≦               ヽ
      i.    /          ̄l 7    1  イ/l/|ヘ ヽヘ ≦   , ,ヘ 、           i
      ,!ヘ. / ‐- 、._   u    |/      l |/ ! ! | ヾ ヾ ヽ_、l イ/l/|/ヽlヘト、      │
.      |〃、!ミ:   -─ゝ、    __ .l         レ二ヽ、 、__∠´_ |/ | ! |  | ヾ ヾヘト、    l
      !_ヒ;    L(.:)_ `ー'"〈:)_,` /       riヽ_(:)_i  '_(:)_/ ! ‐;-、   、__,._-─‐ヽ. ,.-'、
      /`゙i u       ´    ヽ  !        !{   ,!   `   ( } ' (:)〉  ´(.:)`i    |//ニ !
    _/:::::::!             ,,..ゝ!       ゙!   ヽ '      .゙!  7     ̄    | トy'/
_,,. -‐ヘ::::::::::::::ヽ、    r'´~`''‐、  /        !、  ‐=ニ⊃    /!  `ヽ"    u    ;-‐i´
 !    \::::::::::::::ヽ   `ー─ ' /             ヽ  ‐-   / ヽ  ` ̄二)      /ヽト、
 i、     \:::::::::::::::..、  ~" /             ヽ.___,./  //ヽ、 ー        
661デフォルトの名無しさん:2005/05/07(土) 23:48:59
あっセンブリ茶なのね
662デフォルトの名無しさん:2005/05/08(日) 00:25:11
>>653
0と1だけで理解できます。
663デフォルトの名無しさん:2005/05/08(日) 00:39:56
あっ、センズリ中
664デフォルトの名無しさん:2005/05/08(日) 00:52:21
>>663
わしの部屋に監視カメラ付けたのはお主じゃな
665デフォルトの名無しさん:2005/05/08(日) 01:30:46
>>664
となりにいる、動物みたいの何?
666デフォルトの名無しさん:2005/05/08(日) 03:03:32
667デフォルトの名無しさん:2005/05/08(日) 05:40:19
>>655
セマンティクスではそうなるけど
キャストなんかでも変数の型としては
int *
とするんだから
668デフォルトの名無しさん:2005/05/08(日) 07:16:54
>>1
規格では
・オブジェクト(と関数)を指し示すための値
・ポインタ型として宣言されたオブジェクト
・宣言子中の識別子の前の * と型修飾子の並び

K&Rでは他の変数のアドレスを内容とする"変数"

>>667
セマンティクスでもそうはならない。
宣言子中の * は演算子じゃないし。

てかみんな何で規格書読まないの?
669デフォルトの名無しさん:2005/05/08(日) 08:38:32
規格書って何?
670デフォルトの名無しさん:2005/05/08(日) 08:44:03
セマンティクスでそうじゃないの?

int a, *b, c[10], *d();

なんてできるじゃない?
671デフォルトの名無しさん:2005/05/08(日) 10:16:48
【関連スレ】

 ポインタの説明をしてみて初めて解かる難しさ
 http://pc8.2ch.net/test/read.cgi/tech/1084956293/

【関連おもしろスレ】

 C言語のポインタの文法はおかしい
 http://pc8.2ch.net/test/read.cgi/tech/1115419223/

672デフォルトの名無しさん:2005/05/09(月) 10:58:52
>>670

見た目が同じってだけ。
*bと同じ見た目の式はint型だけど*bという宣言子はint型でも何でもない。
constを入れてみたら、別のものだってわかると思う。

int * const b;

という宣言は書けるけど、

* const b

なんて式は書けないよね?
673デフォルトの名無しさん:2005/05/09(月) 11:20:51
>>672
かけるしょ
674デフォルトの名無しさん:2005/05/09(月) 11:43:12
>>673
書けねーよ
675デフォルトの名無しさん:2005/05/10(火) 06:26:05
>>672
言っていることがよく分からないのだけど
宣言子をどう解釈するかはコンパイラの仕事であって
それはシンタックスの問題だと思う
人間は「*bがintになるようなポインタ変数なんだな」と
理解して読んでるんじゃないの?
だからaも*bも**cもカンマで区切って並列に記述するのに躊躇しないんだと思うんだけど
676デフォルトの名無しさん:2005/05/10(火) 06:54:57
http://Y043084.ppp.dion.ne.jp/
wwwwwwwwwwwwwおkwwwうはっwwww
おkwwwっうぇwwwwwwwwwwwwwwwwwwwww
wwwwwwwっうぇwwwwwwっうぇ
677デフォルトの名無しさん:2005/05/10(火) 07:15:10
http://ZB140038.ppp.dion.ne.jp/

wおkwwwっwっうぇwうぇwwwおkwwwwwwwww
っwwwwwwwwwwww
wうぇwww
っwwwwwwwうはっwwwおkwwwwww
wwwwww
678デフォルトの名無しさん:2005/05/10(火) 07:51:04
http://141-189-192.biwa.ne.jp/

wwwwwwっwwwwwwwwwwww
wっうぇ
っうぇっうぇwwwっうぇwwwwwwwwwっうぇ
wwwwwwうはっwwwwwwうぇwwwおkwww
679デフォルトの名無しさん:2005/05/10(火) 09:57:43
うわぁ〜
680デフォルトの名無しさん:2005/05/11(水) 10:56:27
>>675
「人間がどう理解するか」なんて話をいつどこで誰がしたんだ?
規格書の意味規則には「*bがintになるようなポインタ変数」に類することは一切書かれていない
だからセマンティクスでも>>655が言ってることは間違い

655みたいな解釈がしたけりゃ勝手にすればいいが、嘘は書くな
681デフォルトの名無しさん:2005/05/11(水) 14:59:32
int *p とか int* p とか言ってるけど、int * p の3単語で認識するヤツは以内のかしらん
682デフォルトの名無しさん:2005/05/11(水) 15:11:47
関数の戻り値と仮引数はそう書いてる。
void * f(const char * s)
てな感じ。
683デフォルトの名無しさん:2005/05/12(木) 00:26:25
int a=4;
int* b;
b = &a;
int c;
c = *(int*)(unsigned*)(double*)(char*)(long*)b;
if (a==c) puts("別になんともないよ");

こういうのって普通は動作するものなの?
まあ使うこともないんだけど
684デフォルトの名無しさん:2005/05/12(木) 01:02:26
>>683
ポインタは、昔のfarなどを除いて、基本的には
どんな型でも、サイズ(sizeof(type*))が同じ
で、型によって、アドレスが変わるって事はないので、問題ない。ハズ
685デフォルトの名無しさん:2005/05/12(木) 08:30:02
セマンティクスって人間の理解している意味ってことだからだよ
686デフォルトの名無しさん:2005/05/12(木) 08:37:04
>>684

int a=4;
int* b;
b = &a;
int c;
c = *(double*)b;
if ((double)a==c) puts("別になんともないよ");

だったら?
687デフォルトの名無しさん:2005/05/12(木) 13:16:58
語源の話なんか誰もしとりゃせんがな
688デフォルトの名無しさん:2005/05/12(木) 13:50:08
>>686 は、↓がポインタの代入に見えるらしい・・・
c = *(double*)b;
689680じゃないよ:2005/05/12(木) 20:35:10
>>685
こりゃまたトンデモ解釈だな。そんな訳初めて聞いたよ。

Cの作者は、>>675が言うように
>人間は「*bがintになるようなポインタ変数なんだな」と

読ませたかったのかもしれないが、その目論見はどう見ても失敗してて、
こうして混乱してスレ立てたりする奴が出てくるわけだ。
上のような解釈は、既出のようにconstで破綻するし、見ようによっては
関数ポインタでも配列でも破綻する。また、関数の仮引数や、
文字配列の初期化などの例外について、この解釈は何も語ってくれない。

675の言うような解釈を勧めている入門書もあるけど(望洋本とか)
混乱を招くだけだと思うよ。
690デフォルトの名無しさん:2005/05/12(木) 21:48:38
constで破綻するというのは
int * const bの宣言はできるが* const bという式はダメという例?
int const bは宣言できるけどconst bという式はないんじゃないの?
691デフォルトの名無しさん:2005/05/12(木) 21:51:02
>>688
ポインタの代入じゃないんだけど・・・
ポインタのキャストで指されている変数の型のサイズが広がったらって例です
一部間違い

int a=4;
int* b;
b = &a;
double c;
c = *(double*)b;
if ((double)a==c) puts("別になんともないよ");

692デフォルトの名無しさん:2005/05/12(木) 21:55:54
あと、セマンティクスは文字通り「意味」ということ
僕はこれを「人間の解釈」のつもりで使ってきたけど
そうではない用語として使う人もいるってことだね
そのことは理解できました
693デフォルトの名無しさん:2005/05/12(木) 21:58:47
>>683
元と同じポインタ型へ戻せば値不変が保証されるらしいから問題ないだろう。
694698:2005/05/12(木) 23:28:42
>>690
>int const bは宣言できるけどconst bという式はないんじゃないの?

だから破綻するって言ってるんじゃん。いったい何が言いたいの?

そういや、C++の&でも破綻するよな。

>>692
「意味」とは「人間の解釈」のことである、と認識してる奴は珍しいと思うが。
普通こういう文脈でセマンティクスと言えば、文法よりもうワンランク上のレベルの
「意味論」という意味で、
「それ、文法的にはあってるが意味がないぞ」とか言う場合の「意味」という
言葉に近い意味だと思う。
695デフォルトの名無しさん:2005/05/13(金) 01:55:11
代入した時の型と、実際に使う時の型が同じであれば、問題ない
それが異なる場合は、使い方次第

int *a;
double b;
char c=1;
*(a=(void*)&b)=0;
*((char*)a)=c;
if(*((char*)&b)==c)puts("別になんともないよ");
if(*a==(int)c)puts("環境次第")else puts("この使い方は駄目よ");

あまり、良い例じゃないけどね…
696デフォルトの名無しさん:2005/05/13(金) 02:10:02
>代入した時の型と、実際に使う時の型が同じであれば、問題ない

たとえばchar*とint*でポインタのサイズが違うような処理系もあったと思うが。
そういう処理系だと、char*からint*にキャストした時点で情報が失われるんじゃ
ないかな。
697デフォルトの名無しさん:2005/05/13(金) 06:40:26
>>694
うーん、それじゃ、ポインタ変数の宣言でconstをそこに入れるのと
ポインタ変数を使う場合にconstを入れられないのを例示された意味が分からない
僕が追加したのはポインタ変数でなくても宣言にはconstを入れられるし
変数を使う時には入れられないのだからポインタの宣言についてのみ破綻していると
指摘されるいわれはないということなんだけど

*bがintという意味で
int *b
としてもbを定数と宣言するならbにconstがついて
int * const b
になるのは当然に思うよ
698デフォルトの名無しさん:2005/05/13(金) 14:36:12
>>696
聞いた事ないけど、そんな環境があれば、駄目だね
ただ、その場合、
char *cp ;
int *ip ;
cp = malloc ( sizeof(*cp) ) ; /* cpとipでサイズが違うのに */
ip = malloc ( sizeof(*ip) ) ; /* どうやって代入してるの? */
等の処理が特殊であると思われる(ANSI等に準拠してない?)ので、
あまり気にする必要もないかもしれないが…
699デフォルトの名無しさん:2005/05/13(金) 14:39:25
そんなものは無い
near far は昔あったがなー
700デフォルトの名無しさん:2005/05/13(金) 16:57:34
701デフォルトの名無しさん:2005/05/14(土) 00:05:03
64bit環境だとやっぱりポインタも64bitになるんですか?
702デフォルトの名無しさん:2005/05/14(土) 00:32:01
>>700
よう分からんけど、それってANSI等の規格に準拠してるの?
まぁ、準拠しているのであれば、>>698の動的確保が上手く行くはずで
内部的にポインタを自動変換する機構を持っているはずなので、
>>695のように、
>代入した時の型と、実際に使う時の型が同じであれば、問題ない
と思うけどね…

>>701
環境次第でしょ
703デフォルトの名無しさん:2005/05/14(土) 01:28:43
>>702
準拠してるよ。規格では、異なるオブジェクト型へのポインタのキャストを
認めていて、「与えられた境界調整をもつオブジェクトへのポインタは、
同じか、より制限の弱い境界調整をもつオブジェクトへのポインタに
型変換して、再び元に戻してもよいことを保証する」というところまでは
書いてあるが、境界調整の強い方へキャストして戻ることまでは保証してない。
で、動的確保に関して言えば、あらゆるオブジェクト型へのポインタは
void*にキャストすることとvoid*からキャストすることは認められているから
問題ない。
でも、たとえばchar*をint*にキャストしたら、元には戻らないかも知れない。
704デフォルトの名無しさん:2005/05/14(土) 02:11:34
>>703
なるほど
char*やvoid*の方が他のポインタと比べて細かく指定できる
(byteポインタやwordポインタがある)環境では
他のポインタにキャストすると切捨てられる可能性があるって事ね
705694:2005/05/14(土) 13:44:57
>>697
>ポインタ変数を使う場合にconstを入れられないのを例示された意味が分からない

しらんよそんなもん。>>672を書いたのは俺じゃないし。
俺が言ってるのは、プログラミング言語の宣言を読むのに、コンパイラの解釈と
違う解釈をしてもメリットはないだろう、ということ。
オブジェクト指向の説明をするのに犬猫ほ乳類を持ち出すようなもの。

まあ、初心者向けのウソを含む解釈が、初心者の助けになるなら
それを使うのもひとつの手だが、少なくともこの例では混乱を招いている
だけじゃないかと。

int array[10];
int *a = array;

みたいなのを見て混乱した、って話がこのスレの上の方でなかったっけ。
確認しないで書いてるけど。
706680=672だよ:2005/05/14(土) 14:57:58
まだやっとったんか。
constは「破綻する」例として出した訳ではないんだがな。
破綻する例だとしても一つありゃ十分だろ。

それから、
>>675
>宣言子をどう解釈するかはコンパイラの仕事であって
>それはシンタックスの問題だと思う

コンパイラが何をするものなのか理解してないのか。
単に用語を間違ってるだけか?

宣言子をどう解釈するかはセマンティクスの問題だ。
シンタックスの問題は「それが宣言子であるかどうか」だ。
707デフォルトの名無しさん:2005/05/15(日) 10:16:20
ポインタで渡した方が、値がコピーされない分高速になるのでしょうか?
708デフォルトの名無しさん:2005/05/15(日) 10:29:06
>>706
ポインタでも普通の変数でも同じ状況であるなら
「破綻する」としていることが何か分からないけど
ポインタの宣言においてconstを入れることで破綻することって何なの?
宣言死をどう解釈させたいかはコンパイラの設計者の考えているセマンティクスであって
コンパイラはシンタックスに従って形式的に変換していくだけ
コンパイラの設計者の考えているセマンティクスはコンパイラの動作のためのもので
コンパイラを使うプログラマが考えているセマンティクスとは若干違うね
709デフォルトの名無しさん:2005/05/15(日) 10:41:33
>>707
ポインタ渡せば実際の値はコピーされないが、ポインタの値がコピーされますが何か?

int a = 5;

int b = a;
int *p = &a;

これで下の方が早いと思うならまだまだだな
710デフォルトの名無しさん:2005/05/15(日) 10:53:01
>>705
まあ確かに
int *a=array;
の例で初心者は混乱するかもしれないね
けどaの宣言をしているんだから初期値の代入をするのはあくまでa
それは宣言以外の式の中で左辺値として使う場合とは違うと認識しなくちゃいけない
int a[3]={1,2,3};
でも定義されているのはあくまでaでしょ?宣言以外の式の中じゃa[3]にこう代入することはできないわけで
711デフォルトの名無しさん:2005/05/15(日) 10:54:46
>>709
もっとでかい構造を持った変数とかのことじゃない?そういうのを渡せる言語もあるから
712デフォルトの名無しさん:2005/05/15(日) 13:54:52
>>711
ていうかCだって構造体を関数の引数として渡すことできるよな。
だから、ある程度わかっている人同士の会話なら、
「ポインタで渡した方が、値がコピーされない分高速になる」
という言い方で通じるだろうけど、こういうのが現場で「伝承」されていくうちに、
intまでポインタで渡す奴が出てくるというのはありそうな話なわけで… w
713デフォルトの名無しさん:2005/05/15(日) 19:20:20
いくらできるからって構造体を直接値渡しするヤツなんて居るのか?
714デフォルトの名無しさん:2005/05/15(日) 19:23:59
>>712
>だから、ある程度わかっている人同士の会話なら、
考えるまでもなく、ポインタの方が高速な訳で…
どちらかと言えば、教えた人の言葉の一部分だけを捉えて
勘違いする奴がいるだけではないかと…
715デフォルトの名無しさん:2005/05/15(日) 19:34:29
>>713
Win32APIなんかはPOINT(メンバはintが2つ)くらいだと値渡ししている。
716デフォルトの名無しさん:2005/05/15(日) 19:53:24
そんなことしてるAPIあったのか・・・
GetWindowRectとか、受け取るのに構造体使ってるのしか使ったこと無いから知らねぇな・・・
717デフォルトの名無しさん:2005/05/15(日) 21:20:33
>>713
64bitの値でlong longを使いたくない(使えない)場合は構造体を使って値渡しやね
718デフォルトの名無しさん:2005/05/15(日) 21:56:53
オセロの先読みルーチン作るとき、再帰的に先読みするんだけど、
各手を売った後の盤面の構造体(enum 8×8の配列含む)を値渡ししてたな。
もちろんこれは必要性があってやったわけだけど。
719デフォルトの名無しさん:2005/05/15(日) 22:18:19
>>718
うむ。その場合は盤面をまるっと渡したほうが楽だな。
720デフォルトの名無しさん:2005/05/16(月) 19:11:17
>>710
同意だが誰がどういう主張をしているのかもう少しちゃんと読め、と。
あと、>>708はもう放っといてやれ
721デフォルトの名無しさん:2005/05/16(月) 20:04:32
おまいら、構造体の値渡しの時、calloc()でメモリ領域取得しないんですか?

#include <stdlib.h>

#define B_SIZE 8
typedef enum { empty=0, white=1, black=2 } CellState;
typedef struct {
 CellState at[B_SIZE][B_SIZE];
} Board;

void bar(Borard b) {
for (int i=0; i<B_SIZE)
  for (int j=0l j<B_SIZE)
   b.at[i][j] = empty;
}

// 引数で渡された構造体ポインターの中身は、書き換えたくない
void foo(const Board *b_ptr) {

 // calloc()で構造体を、ローカル変数領域(スタック上)にぴーこ
 Board *b_copy = (Board *)calloc(1, sizeof(Board));
 memcpy(b_copy, b_ptr, sizeof(Board));

 // ぴーこした構造体を渡す 
 bar(b_copy);

 // リターン時、b_copyに確保した領域は自動的に開放される
}
722デフォルトの名無しさん:2005/05/16(月) 20:16:07
> // リターン時、b_copyに確保した領域は自動的に開放される

されねーよ
ていうかそのまま渡せや
723デフォルトの名無しさん:2005/05/16(月) 20:16:45
おまえそれ超おかしいから
724デフォルトの名無しさん:2005/05/16(月) 20:44:18
>>722
おまえそれ蝶美味しいから
725723:2005/05/16(月) 21:03:32
>>721宛な
726デフォルトの名無しさん:2005/05/16(月) 21:04:55
Board *b_copy宣言なのに
bar(b_copy)でいけるしそれで値渡しだと思ってる>>721に蝶ワロス
727デフォルトの名無しさん:2005/05/16(月) 21:14:44
あ?
関数宣言は void bar(Board b); だから、
呼び出し側も Board *b_ptr; bar(*b);って補完してねっ☆おねぇさんのお願い

やっぱvoid *calloc(size_t)知らなかっただろ?

この情報は為になりましたか? (●とても役に立った ○大変役に立った)


728デフォルトの名無しさん:2005/05/16(月) 21:15:52
× Board *b_ptr; bar(*b);
◎ Board *b_ptr; bar(*b_ptr);
729デフォルトの名無しさん:2005/05/16(月) 21:19:46
>>727
まぁまぁ、そう慌てなさんなw
730デフォルトの名無しさん:2005/05/16(月) 21:31:44
>>722
calloc()が確保したメモリは、
ローカル変数と同じ、スタック上に確保されるんで、
ローカル変数同様、関数を飛び出た直後に解放される
731デフォルトの名無しさん:2005/05/16(月) 22:24:24
>>
>>730
calloc
要素を 0 に初期化した状態で、メモリ内に配列を割り当てます。

alloca
スタックにメモリを確保します。
732デフォルトの名無しさん:2005/05/16(月) 22:26:39
きゃん!
733デフォルトの名無しさん:2005/05/16(月) 22:29:14
ワロス
734デフォルトの名無しさん:2005/05/16(月) 22:33:49
くぅーん
735デフォルトの名無しさん:2005/05/16(月) 22:34:39
ちなみにサイズがあらかじめわかっているものにallocaを使うのはただのバカ。
ただのローカル変数の方がずっと良い。
736デフォルトの名無しさん:2005/05/16(月) 22:38:33
そゆこと。

さっき書きかけたんだけど、おねぇさんに逆らうスカポンタンが居たから廃棄した
737デフォルトの名無しさん:2005/05/17(火) 01:07:40
昔、デフォルト4kスタックのころにalloca使われてえらいめにあった
今は平気なんだろうけど抵抗あるな・・・
738デフォルトの名無しさん:2005/05/17(火) 11:54:22
>>737
今でもデフォルトのスタックはそんなに多くないぞ。
739デフォルトの名無しさん:2005/05/17(火) 12:15:49
デフォルト1MBじゃなかったっけ
740喜屋武:2005/05/18(水) 15:10:09
>>732
呼びましたか?
741デフォルトの名無しさん:2005/05/18(水) 21:26:18
可変長配列を宣言できないコンパイラが多すぎる
742デフォルトの名無しさん:2005/05/18(水) 22:32:58
俺はC89に対応していれば十分。
743デフォルトの名無しさん:2005/05/18(水) 23:54:37
できないときは、とりあえず[1]で
744デフォルトの名無しさん:2005/05/20(金) 13:53:02
return _alloca(sizeof(NULLPO));
745デフォルトの名無しさん:2005/06/28(火) 23:37:49
age
746デフォルトの名無しさん:2005/06/29(水) 10:48:44
ポインタのポインタのことで質問なのですが、どういうときに使われるのでしょうか?
ポインタ配列のポインターとして使うのは、わかったのですが他にどう使うのかがわかりません。
たとえば、二分探索木で使われているのですが、これの使い方が理解できません。
747デフォルトの名無しさん:2005/06/29(水) 11:18:23
m9
748デフォルトの名無しさん:2005/06/29(水) 15:00:50
たとえばポインタxのアドレスがもう一個のポインタyに入ってるとする。
するとyはxのポインタ、つまりポインタのポインタである。
って事はどうなるの

749デフォルトの名無しさん:2005/06/29(水) 15:38:39
struct structure_def {
char *strings;
};

structure_def *structure;
750デフォルトの名無しさん:2005/06/29(水) 15:59:27
>>748

char c1[3] = "c1"; // c, 1, \0
char c2[3] = "c2"; // c, 2, \0
char* x;
char** y;

x = c1; // xの値はc1のアドレス(c1[3]の先頭アドレス)「100」(仮定)
y = &x; // yの値はxのアドレス「200」(仮定)

printf("xを参照:%s\n", x);

// printf()の第2引数に「*y」を指定する。つまりprintf()の中では
// ポインタの2枚剥がし(xを経由してc1を参照)が行われる。
printf("yを参照:%s\n", *y); // ・・・・・・・・・・・・・(1)

x = c2; // xの値はc2のアドレス(c2[3]の先頭アドレス)「150」(仮定)

//(1)以降はyへの代入を行っていないにもかかわらず以下の結果は(1)と異なる
printf("yを参照:%s\n", *y);
751デフォルトの名無しさん:2005/06/29(水) 20:29:02
DirectXのメソッドなどだとよくポインタのポインタがある
752デフォルトの名無しさん:2005/06/29(水) 22:56:56
というよりCOMをCで使おうとするとポインタのポインタはよく出てくる。C++だと参照がある分、楽だ。

それはともかくとして、「引数」に値を代入したいときにはポインタにする。
void f1(int *a, int b)
{
    *a = b;
}
その「引数」の型がたまたまポインタだったりすると結果はポインタのポインタになる。
void f2(int **a, int *b)
{
    *a = b;
}
ようするにそれだけなんだけどね。
753デフォルトの名無しさん:2005/06/30(木) 02:24:28
要するにCでは値渡ししかできないので、参照渡しみたいなことをするためには
ボインタのボインタが必要ってことね。
754デフォルトの名無しさん:2005/06/30(木) 06:11:01
>>753
ポインタを参照渡ししたいなら、な
755デフォルトの名無しさん:2005/06/30(木) 10:48:17
char c1[3] = "c1"; // c, 1, \0
char* x;
char** y;
char*** z;

x = c1; // xの値はc1のアドレス(c1[3]の先頭アドレス)「100」(仮定)
y = &x; // yの値はxのアドレス「200」(仮定)
z = &y;

printf("xを参照:%s\n", x);

// printf()の第2引数に「*y」を指定する。つまりprintf()の中では
// ポインタの2枚剥がし(xを経由してc1を参照)が行われる。
printf("yを参照:%s\n", *y); // ・・・・・・・・・・・・・(1)

// 3枚剥がし!
printf("zを参照:%s\n", **z);
756デフォルトの名無しさん:2005/07/01(金) 14:17:27
昔仕事暇時の遊び(たいした仕事じゃなかった)で
全ての変数を**************つけて定義してみた。

コンパイルしてバイナリ(obj)比較したら変わらんかった。
& -1 * +1 [] +1という感じで差を数えてたのかな。
757デフォルトの名無しさん:2005/07/02(土) 23:47:20
ポインタを経由し無ければできない事って何んですか?
758デフォルトの名無しさん:2005/07/02(土) 23:59:46
>>757
たとえばこんなとき。
#include <stdio.h>
void f1(int n)
{
  n = 64;
}
void f2(int *p)
{
  *p = 64;
}

int main(void)
{
  int n = 1;
  printf("%d", n);
  f1(n);
  printf("%d", n);
  f2(&n);
  printf("%d", n);
  return 0;
}
ほかにも配列を引数として渡すには問答無用でポインタにするしかないし、構造体もポインタ渡しの方が効率が良いことが多い。
(配列・構造体を引数にするとき、こういう風に関数内で中身を書き換える場合以外はconstポインタを使う。)
759デフォルトの名無しさん:2005/07/03(日) 01:29:03
double **x;
x = new double[n][m];
ってアリですか。
ナシなら2次元の場合どうしたらシアワセになれますか
760デフォルトの名無しさん:2005/07/03(日) 02:05:40
#include <iostream>

#define LENGTH 10
#define HEIGHT 5

int main(int argc, char* argv[])
{
double **x = new double*[HEIGHT];

for (int i = 0; i < HEIGHT ; i++)
{
x[i] = new double[LENGTH];
}

for (int j = 0; j < HEIGHT; j++)
{
delete[] x[i];
}

delete[] x;

return 0;
}
761760:2005/07/03(日) 02:10:13
バグあり。
delete[] x[j];
762デフォルトの名無しさん:2005/07/03(日) 02:18:17
できた。>>760先生にシアワセが訪れますように。
763デフォルトの名無しさん:2005/07/07(木) 16:00:31
c言語で1000以下の素数を二つ足し合わせて1000になるプログラムってどうすればいいんですか?わかる方いましたらお願いします。できるだけ初心者でも理解できるものでお願いします。


764デフォルトの名無しさん:2005/07/07(木) 16:21:46
>>763
1000以下の素数を求めて、足したら1000になる組み合わせを探す
765デフォルトの名無しさん:2005/07/07(木) 17:54:37
>>763
マルチすんな。
766デフォルトの名無しさん:2005/07/07(木) 19:17:35
他のとこでも言ってきたのですが、今回書き込みするのが初めてだったのでここのマナーを知らずにすみませんでした。次からは気をつけたいと思います。本当にすみませんでした。
767デフォルトの名無しさん:2005/07/07(木) 21:44:00
死ねクズ
768デフォルトの名無しさん:2005/07/07(木) 21:48:21
まぁ許してやれよ
769デフォルトの名無しさん:2005/07/07(木) 21:58:58
double **x;

x = new double*[n];
*x = new double[n*m];
for(int i=1; i<n; i++)
x[i] = x[i-1]+m;

delete[] *x;
delete[] x;
770デフォルトの名無しさん:2005/07/07(木) 22:12:50
>>764
それは効率が悪くないか?
ゴールドバッハの予想を使えば少し効率良く処理できるかと。
771デフォルトの名無しさん:2005/07/08(金) 01:48:06
>>38
真実

アセンブラでできることをシンプルに実装してるからなCは
772日本道路公団:2005/07/08(金) 02:46:05
C言語の学習での山場ってどこですか?
773デフォルトの名無しさん:2005/07/08(金) 03:22:24
774デフォルトの名無しさん:2005/07/08(金) 03:46:00
前半の山場はポインタ、中盤はクイックソート、終盤は線形リスト
意外とおもしろいのがインラインアセンブラ
775デフォルトの名無しさん:2005/07/08(金) 19:43:52
>>771
オ-バー風呂-とか消えてしまない?
Cは何かと不便なきが。
776デフォルトの名無しさん:2005/07/08(金) 20:13:11
>>775
まずはそのダメダメな日本語を消さないとな
777デフォルトの名無しさん:2005/07/09(土) 04:36:01
>>774
リストやソートや検索のお勉強で脳ミソからお熱をあげる人(おれ)ってプログラミング向いてない?
ポインタはなんとかクリアしたはずなのにな
778デフォルトの名無しさん:2005/07/09(土) 14:38:49
>>777
最初は誰でもそう。
初めから全部わかったら天才か基地外。
779デフォルトの名無しさん:2005/07/09(土) 22:01:17
ポインタちょーうぜー!
780デフォルトの名無しさん:2005/07/09(土) 22:30:42
一度ポインタの良さを味わったら忘れられない体になる
781デフォルトの名無しさん:2005/07/10(日) 14:57:46
>>780
エロい表現ですね
782デフォルトの名無しさん:2005/07/13(水) 14:33:50
頭では配列でいいやと思っても
嫌がおうにもポインタを使ってしまう体になる。
783デフォルトの名無しさん:2005/07/13(水) 23:49:21
>>782
あまりエロくない表現ですね
784デフォルトの名無しさん:2005/07/15(金) 00:43:49
初心者って配列にすれば分かりやすくなるところを、なぜか頑張って
ポインタ使ってスパゲッティなコード書くよな
785デフォルトの名無しさん:2005/07/15(金) 07:51:23
>>753
  _, ._
( ゚ Д゚) ・・・

  _, ._
( ´ Д⊂ ゴシゴシ

  _, ._
( ゚ Д゚) ・・・
786デフォルトの名無しさん:2005/07/15(金) 16:34:34
まあボインタがなくても参照私みたいなことは出来る罠。
ていうかボインタって何ですか?調べたけど解りませんでした
787デフォルトの名無しさん:2005/07/15(金) 18:10:10
おっぱいが大きい人を参照するのに使う
788デフォルトの名無しさん:2005/07/15(金) 20:29:41
そいつはボインだ
789デフォルトの名無しさん:2005/07/15(金) 20:30:40
……って、本当に bo って書いてあるよママンっていうか見間違えてスマヌ
790デフォルトの名無しさん:2005/07/20(水) 23:45:09
この速度ならぬるぽ
791デフォルトの名無しさん:2005/07/20(水) 23:56:42
この速度でもガッ
792デフォルトの名無しさん:2005/07/31(日) 11:02:21
この速度ならぬるぽ
793デフォルトの名無しさん:2005/08/06(土) 07:45:54
この速度だからガッ
794デフォルトの名無しさん:2005/08/19(金) 23:43:46
あげ
795デフォルトの名無しさん:2005/08/20(土) 00:10:10
あ?だからさぁポインタつーのは、おまえのマシンについてるメインメモリの番地だろ?
おまえのマシンに512MBのメモリが刺さってたら、
ポインタってのは 0〜536870912(512MB) の範囲のメモリ位置をあらわす数値なんだよ。

int a = 100;
int* ap = &a;
printf("ap=%d\n", ap);

とかいうコード書くと ap=2293596 とか表示されるだろ?
つまり、おまえのマシンに突き刺さってるメモリの、
2293596番目に変数aの100が格納されてんだよ。

    ↓2293596番目
┏━━━━━━━━━━━━━━┓
┃  〜 100 〜        ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━┛
0              536870912(512MB)

まあ、今時のOSはみんな仮想メモリだから、
実際の物理的なメモリの2293596にアクセスしてるかどうかはわからんのだが。
796795:2005/08/20(土) 00:11:18
ず、ずれた…。

    ↓2293596番目
┏━━━━━━━━━━━━━━┓
┃  〜 100 〜             ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━┛
0                     536870912(512MB)
797デフォルトの名無しさん:2005/08/20(土) 03:06:45
>>796
別に三角形でもいいじゃないか。
798デフォルトの名無しさん:2005/08/20(土) 06:10:58
あなる程
分かりやすい

変数をメモリ以上使ったらどうなりますか?
799デフォルトの名無しさん:2005/08/20(土) 06:15:15
仮想メモリ、MMU
800デフォルトの名無しさん:2005/08/20(土) 15:01:43
1.
>おまえのマシンに512MBのメモリが刺さってたら、
>ポインタってのは 0〜536870912(512MB) の範囲のメモリ位置をあらわす数値なんだよ。
2.
>まあ、今時のOSはみんな仮想メモリだから、
>実際の物理的なメモリの2293596にアクセスしてるかどうかはわからんのだが。

2.があやふやだから、1.がおかしい
プロテクトモードでも、セグメント切り替え、64kの壁て知ってるか?
と、初歩向けの答えに突っ込みを入れてみるw
801デフォルトの名無しさん:2005/08/20(土) 15:19:33
>799
MMUは変数をメモリ以上使わなくとも使っている、プロテクトモードなら。
そもそもMMUは、物理メモリを論理メモリに変換するCPUの機能
何故、そんなことをするかというと、
・システムとして重要なアドレスエリアをユーザに使われないようOSがプロテクトモードの階層(権限)(Penに設定できるレジスタがあったと思う)により制限を掛けるため。
(もし、アクセスするとアドレス保護例外(CPUが出す例外)が起こる)
・プログラム同士のアドレスをお互いに侵食しないために利用アドレスを分けている。
(プロテクトモードでユーザから見て0番地でも、実際は全く違う。更に言うと、ユーザから見て0番地が多数存在する)

あとは、IDT(割り込みベクタテーブル)のCPUの外から見える存在アドレスを変えることにより、
独自に(OS上に)割り込みベクタテーブルをカスタマイズできるというのもある

それと、これはMMUでなく、プロテクトモードの機能だけど、階層(権限)により、システム上重要なアセンブラ命令をユーザに使わせないようにしている>特権命令(OSが設定)
802795:2005/08/21(日) 01:23:36
>>797
!?なんて柔軟な発想!

>>798
あなる程・・・アナル程・・・。
えーっと、しらん。なんか仮想メモリ的なものでがんばるんじゃないか?

>>800
1.がおかしいのは説明用の文章だから。
2.があやふやなのは、漏れがそこまで仮想メモリについての知識を持ってるわけじゃないから。
803795:2005/08/21(日) 01:32:23
あ、で、ポインタ型について説明してないね。
ポインタ型は4バイトのメモリアドレスを管理する変数。
ポインタもメモリのどっかに4バイト確保してメモリアドレスの数値を管理するもの。

  // コード
  int a;
  int* ap = &a;
  printf("a =%d\n", a);
  printf("&a =%d\n", &a);
  printf("ap =%d\n", ap);
  printf("&ap =%d\n", &ap);
  
  // 上記コードの実行結果
  a =100
  &a =2293596
  ap =2293596
  &ap =2293592

↑みたいなコードだと↓みたいなイメージになる。

    ↓2293592番目(ap)
┏━━━━━━━━━━━━━━━━━━━┓
┃  〜 | 2293596 | 100 | 〜             ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━┛
0          ↑2293596番目(a)        536870912(512MB)
804795:2005/08/21(日) 01:34:01
>>797
あっ、すいません。三角形は無理ですた。
805デフォルトの名無しさん:2005/08/21(日) 13:10:27
>803
あ?
あせって書かなくていいんだよ。
だいたいなんで、
int* ap = &a
とポインタ参照なのに、先頭アドレスが違ってるんだ、そこでおかしいと思わなかったか?
で、&apてなんだ?
変数aの指す先頭アドレスは&a
変数apの指す先頭アドレスはapだろう
apにある値は*apだろう
図が無茶苦茶だなぁ
806795:2005/08/21(日) 14:58:55
>>805
ん?どのへんがわからないんだ?

>変数aの指す先頭アドレスは&a
「変数aの指す」というよりは変数aの先頭アドレスはのほうがしっくりくるな。

>で、&apてなんだ?
>変数apの指す先頭アドレスはapだろう
そうだね。それでap自体のアドレスが&apだろ。

俺は最終的にポインタ型はchar*だろうとint*だろうとdouble*だろうと
4バイトの整数型ということが言いたいんだが。
↓のコードでわかるかな。アドレス値を int で受け取ってみた。

int a = 100;
int ap = (int)&a;
printf("a =%d\n", a);
printf("&a =%d\n", &a);
printf("*ap =%d\n", *((int*)ap));
printf("ap =%d\n", ap);
printf("&ap =%d\n", &ap);

a =100
&a =2293596
*ap =100
ap =2293596
&ap =2293592
807795:2005/08/21(日) 15:09:03
つまり、↓のようなコードを書くとメモリの100番目を int 型のデータとして見る。

int a=100;
printf("&a=%d\n", &a);
printf("*a=%d\n", *((int*)a));

//実行結果
&a=2293596
(※ここでアドレス保護だかでプログラムが落ちる

   ↓100番目( *((int*)a) )
┏━━━━━━━━━━━━━━━━━━━┓
┃  | 不明 | 〜 | 100 | 〜             ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━┛
0          ↑2293596番目(a)        536870912(512MB)

*演算子というのは、中身をアドレス値として評価し、その番地のメモリにアクセスをして見る演算子。
今回は100が入っていたので100番目にアクセスしていって、
100番目はちょっとアクセスしてはいけない領域だったから落ちたと。int*にキャストしてるのはえーと説明めんどい。
808つりじゃないか?:2005/08/21(日) 15:17:59
>806
さきと変わたな。
>int* ap = &a;

>int ap = (int)&a;
になった。
つりだとおもうけど、さっきと状況一変したぞ。
今度は参照ではない。単にアドレス値をint型へ代入してる。
だから、&aと&apのアドレスが違う。
それと、
さきの&apてなんだ?だが、
int* ap
と宣言しておいて、int**を求めるいうことか?
これは何を意味するのか分からない、 俺の脳みそが足らないだけかもしれないけど。
809795:2005/08/21(日) 15:35:05
>>808
うーん、そうだな。最終的にポインタ型もデータなのよ。メモリにデータとして確保される。
int* ap;と宣言するとメモリに↓こんな感じで ap のデータ領域が確保される。

     ↓2293592番目(ap)
┏━━━━━━━━━━━━━━━━━━━┓
┃  〜 |  不 定  | 〜               ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━┛
0     ← 4bytes →                 536870912(512MB)

なにも代入していないので中身は「不定」と書かせてもらった。
で、aという変数が2293596番目にあるとして ap = &a; とすると↓のようになる。

     ↓2293592番目(ap)
┏━━━━━━━━━━━━━━━━━━━┓
┃  〜 | 2293596 | 100 | 〜            ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━┛
0            ↑2293596番目(a)      536870912(512MB)

つまり、ポインタを宣言するのは int型を宣言すると一緒なのよ。
だから、int* ap; を &ap とするとそのデータへの先頭アドレス(2293592番目)が返ってくるわけよ。
上に書いたコードをコンパイルして色々試してみるとわかるよ。
810デフォルトの名無しさん:2005/08/21(日) 15:37:16
ポインタが4バイトというのは処理系を限定した話だし、
そもそもポインタは、アドレスを格納するだけのものではない。
型付けという重要な役割を持っている。
811795:2005/08/21(日) 15:38:37
×つまり、ポインタを宣言するのは int型を宣言すると一緒なのよ
○つまり、ポインタを宣言するのは 4byteの整数型を宣言すると一緒なのよ

の方がわかりやすいかね。
812デフォルトの名無しさん:2005/08/21(日) 15:42:47
ちがうな。

つまり、宣言によって、ある一定サイズのメモリエリアが確保されるという意味においては、
ポインタ型も他の組み込み型といっしょなのよ。


というべきだ。
813795:2005/08/21(日) 15:48:03
>>810
まあ、たしかにね。「初歩を理解する上では」という意味で説明をしたわけよ。
「型付け」に関してもまず何が入っているか説明した方がわかりやすいだろうし。
それに処理系を限定して具体的な話をしたほうがわかりやすいだろ。

なぜポインタが4バイトなのかは、32bit(4bytes) CPUだから4バイトが扱いやすいとか、
今の4バイトのポインタでは、4バイトで表現できる最大の4ギガ(4294967296)までが、
扱えるメモリの限界とか色々まわりのこともわかってくるわけだし。
814795:2005/08/21(日) 15:54:38
だから 64bit CPU になったときは状況が変わtt
あっ、>>812えーと。そうだね。でもそれだと初心者は意味わかんなくね?

だから、>>1みたいなまだ理解が浅い人が、
そういう抽象的な説明をされて意味わからなくてこういうスレを建てちゃうわけよ。
815デフォルトの名無しさん:2005/08/21(日) 15:58:23
int サイズやpポインタサイズは処理系によって違う。
現在多く普及しているWindowsでは、どちらも32bitであることが一般的である。
ここでは、特に断りない場合intやポインタ型は32bit(4bye)として話を進める。


と最初にかいときゃいいじゃん。むしろこういうのが一番大事。
816795:2005/08/21(日) 16:13:41
>>815
すんませんでした。
817デフォルトの名無しさん:2005/08/21(日) 16:18:10
>809
それは違うだろう
>803でしっかり、
&a =2293596
ap =2293596
アドレス一緒という結果が出ている。
だから、>809のapと&aのアドレスが違っている図はおかしい。
でだ、そちらに参照の確認の意味でいい極短コードを渡すよ。
#include<stdio.h>
voidmain(){
inta=1;
int* b=&a;
printf("%d\n",*b);
*b=2;
printf("%d\n",a);
}
.c(c)でも.cpp(cpp)でもどちらでもこのまま試せる
818デフォルトの名無しさん:2005/08/21(日) 16:29:20
>817はintだがcharだと状況は一変してくる
#include<stdio.h>
#include<string.h>

voidmain(){
chara;
strcpy(&a,"あい");
char*b=&a;
printf("%s\n",b);
b="うえ";
printf("%s\n",&a);
}
Cでは変数は頭で宣言しなければならないから、.cppでないと試せないが、
.cでやるなら、char aの次にchar* b=""とでもしておいて、strcpyの後、b=&aとでもすればいい
intでは=は参照を意味したが、charでは代入の様相を呈してくる。
なぜなら、""自体が入れ物(アドレス)だから。
"あい"と"うえ"は違う入れ物だから。
&aがbのアドレスが変わったことを知ることはできない。
=はアドレスだけがコピーされ実体はコピーされていない。
だから、&aの内容は"あい"のままになる。
819795:2005/08/21(日) 16:33:42
>>817
ん?そうではないとすると、じゃあ↓これはどう説明するんだ?
#include<stdio.h>
void main(){
  int a=1;
  int a2=999;
  int* b=&a;
  int** c=&b;
  printf("%d\n",*b);
  *b=2;
  printf("%d\n",a);
  *c=&a2;
  printf("%d\n",*b);
  *b=255;
  printf("%d\n",a2);
  printf("%d\n",a);
}
820デフォルトの名無しさん:2005/08/21(日) 17:59:36
#include<stdio.h>

void main(){
int a=1;
int a2=999;
int* b=&a;
int** c=&b;
printf("%d\n",*b);
*b=2;
printf("%d\n",a);
printf("%d\n",b);
*c=&a2;
printf("%d\n",*b);
printf("%d\n",a);
printf("%d\n",b);
*b=255;
printf("%d\n",a2);
printf("%d\n",a);
}
を試したら、途中でbのアドレスが変わったな。
それで、&aのbへの参照が開放された。(&aはbのアドレスが変わったことは分からないから、a=2という実体だけが残る)
おそらくbのアドレスが変わったのはint**cの影響だと思うけど、まだint**が分かんないなぁ
こんな程度ですまないね
821デフォルトの名無しさん:2005/08/21(日) 18:39:25
もしかして、**てアドレッシングと関係あるのかね、アドレスのアドレスて。
Pentiumの持ってるアドレッシング方式と、OSがコードを翻訳したとき放つ命令セットを分かってないけど
&bが4byteスライドして動いている
822デフォルトの名無しさん:2005/08/21(日) 18:42:59
失礼
>OSがコードを翻訳
>コンパイラがコードを翻訳
823デフォルトの名無しさん:2005/08/21(日) 19:26:05
憶測の域を出ないけど
int*でebp(ベースアドレス)+esi(インデックス)を表し
int**でebp(ベースアドレス)を表すんじゃないかなと思た
32bitの場合にはesiで4byteじゃないかなと
int** c=&b;
でベースインデックスアドレス指定だったのが
*c=&a2;
でベースアドレスをしていていて、それでアドレスが4byte動いたのかなと
推測ですみませんね
違っていて、もしよかったら指摘してください
824マイク ◆yrBrqfF1Ew :2005/08/21(日) 19:32:44
キモイレジスタなんかどうでもいいよ
825795:2005/08/21(日) 22:47:25
うーん、↓で納得できんかね?

int a=100;
int ap = &a;
int app = ≈

printf("a=%d\n", a);// a=100
printf("&a=%d\n", &a);// &a=2293596
printf("ap=%d\n", ap);// ap=2293596
printf("*ap=%d\n", *ap);// *ap=100
printf("&ap=%d\n", &ap);// &ap=2293592
printf("app=%d\n", app);// app=2293592
printf("*app=%d\n", *app);// *app=2293596
printf("&app=%d\n", &app);// &app=2293588

    ↓2293588番目(app)   ↓2293596番目(a)
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃  〜| 2293592 | 2293596 | 100 | 〜           ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━━━━━┛
0         ↑2293592番目(ap)              536870912(512MB)

ポインタも単に「整数値」を保存するデータ型。
appは2293588というアドレスに「2293592」という整数を保存した整数データ。
apは2293592というアドレスに「2293596」という整数を保存した整数データ。
aは2293596というアドレスに「100」という整数を保存した整数データ。

ゆえにひねくれた解釈をすると、
*app は *((int**)2293592) と等価。
*ap は *((int*)2293596) と等価になる。
826795:2005/08/21(日) 22:49:15
もしここで b という変数を追加したとするとこんな感じになる。

int b=200;
int a=100;
int* ap = &a;
int** app = ≈

    ↓2293588番目(app)   ↓2293596番目(a)
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 〜 | 2293592 | 2293596 | 100 | 200 | 〜     ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━━━━━┛
0         ↑2293592番目(ap)  ↑2293600番目(b)  536870912(512MB)

こういう状況でもし↓こういうコードを書いたとしたら、
*app = &b;

    ↓2293588番目(app)   ↓2293596番目(a)
┏━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 〜 | 2293592 | 2293600 | 100 | 200 | 〜     ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━━━━━━━━━━┛
0         ↑2293592番目(ap)  ↑2293600番目(b)  536870912(512MB)

&bは2293600なので、apの中身が 2293596 から 2293600 に変わると。
この状況では、apは2293600をさしているので *ap=400 とかやると、
b(2293600)の中身が 400 に変わると。

>>823
レジスタとかわからんちん。
827795:2005/08/21(日) 22:50:44
微妙に図中の矢印がずれた('A`)
828795:2005/08/21(日) 23:22:16
でも、上記のポインタを「メモリアドレスを格納する整数値」で実装する方法は、
MSのC言語とかGCCのC言語による、ポインタの実装であって、
C言語の仕様としてはポインタは整数値で管理しているとは記されてはいないというのを読んだことがあるけど。

・・・って >>532 ここかぁー!

でも今後、新しいCコンパイラが出たとしても、
このポインタを「メモリアドレスを格納する整数値」で実装する方法は変わらないでしょうね。
大体のコンパイラでは、こういう実装なのに>>532みたいな発言するのは初心者が混乱するんでやめてほしい。
829デフォルトの名無しさん:2005/08/21(日) 23:26:25
gccは、どうなるかわからんぞ。4.0で中間言語を一回はさむようになってるからな。
ポインタがアドレスである必要はないし、むしろそういう規定は柔軟性を損なわせる。
830795:2005/08/21(日) 23:38:18
>>829
(;・∀・)ちゅ、中間言語・・・?Javaのようになるん!?
ぼくのしってるgccもかわっちゃったなぁ。というか最近のC言語もすごいなぁ。
そうなると俺もC言語のポインタってなんですか?っていうスレたてちゃうかも('A`)
831デフォルトの名無しさん:2005/08/22(月) 00:02:22
>>830
中間言語の存在はコンパイル中だけで出力されるオブジェクトファイルは機械語だよ。
832デフォルトの名無しさん:2005/08/22(月) 11:38:24
>>829
中間言語(仮想コード)にするのは 4.0 以前からやっていた筈だけど?
4.0 は各言語に合わせた最適化をするようになったんだと思った。
833デフォルトの名無しさん:2005/08/22(月) 13:23:27
ポインタってだけで一冊本ができてしまいますよね.
834デフォルトの名無しさん:2005/08/22(月) 14:06:15
>>833
1冊ではありません。amazon.co.jp で「C ポインタ」をキーにして
和書の検索をすると17冊出てきます。
835デフォルトの名無しさん:2005/08/22(月) 14:20:06
ポインタのポインタとかって使うの?
836デフォルトの名無しさん:2005/08/22(月) 14:21:46
Herbert Schildtが言うには後々便利なことが分かるらしいです.
837デフォルトの名無しさん:2005/08/22(月) 14:32:12
>>835
文字列の配列とかで使いますね。


char *s[] = {"Hello", "2ch"};
838デフォルトの名無しさん:2005/08/22(月) 14:55:29
DirectXを使ってる時もポインタのポインタ出まくりんぐ
839デフォルトの名無しさん:2005/08/22(月) 20:25:23
>>835
たとえばこんな感じに。
void GetMem(void **pp)
{
    *p = malloc(0x100);
}
別に普通の型へのポインタと変わらない。
void GetRand(int *p)
{
    *p = rand();
}
840デフォルトの名無しさん:2005/08/22(月) 22:29:06
C++慣れている奴でも
クラスのメンバ関数の関数ポインタ型の定義を書けと言われて
即時答えられる奴は少ない
841デフォルトの名無しさん:2005/08/22(月) 23:14:26
>>840
そこにコンパイラがあればささっと書くだけ。
#include <iostream>
#include <typeinfo>
struct hoge
{
    void f();
};

int main()
{
    std::cout << typeid (&hoge::f).name() << std::endl;
}
842デフォルトの名無しさん:2005/08/23(火) 00:08:09
>>840
たしかに。定義としかも呼び出し方法も即答できないね。あれは。

Klass k;
void (Klass::*aho)(void) = &Klass::method;
((k).*aho)(); // インスタンスにメソッドポインタを関連付けて呼び出し

こりゃねえだろ → ((k).*aho)()
それとも、もっと簡単にかける?
843デフォルトの名無しさん:2005/08/23(火) 00:09:32
>>842
(k.*aho)()
844デフォルトの名無しさん:2005/08/23(火) 00:15:28
>>843
まじだ。できた。
それでもまだ数日後に覚えていられるかは微妙(笑
845デフォルトの名無しさん:2005/08/23(火) 00:40:09
もしかしてふつうの関数ポインタが

fp();



(*fp)();

のどっちでもコールできるの知らないのか?
846デフォルトの名無しさん:2005/08/23(火) 01:00:59
>>844
.と*の二つで.*となって一つの演算子。->*は三つで一つの演算子。
というように覚えると早い。->が-と>に分けられないのと同じで。
847デフォルトの名無しさん:2005/08/23(火) 08:57:03
>>845
普通の関数ポインタはそうなんだが、C++のメンバへのポインタを使って関数呼び出しするときには844のようにするしかない。
848デフォルトの名無しさん:2005/08/24(水) 01:49:44
>>845
それは知ってる。
むしろ
(******************fp)();
でも呼べるのも知ってる。

>>846
おお、それはおぼえやすいかもしれん。
849デフォルトの名無しさん:2005/08/24(水) 19:12:29
生産的なことに労力を使おう。
850デフォルトの名無しさん:2005/08/25(木) 22:12:50
".*"も"->*"も、そのものが一つの演算子なんですよ。
意味無いけどオーバーロードできるし。
851デフォルトの名無しさん:2005/08/25(木) 22:21:55
>>850
.*はオーバーロードできない。 . もオーバーロードをできないからそれに合わせて。
852デフォルトの名無しさん:2005/08/27(土) 14:43:06
ポインタが他の変数のアドレスを入れる変数ってことはわかったけど
ポインタという変数のアドレスへのポインタはどの変数が持っているの?
853デフォルトの名無しさん:2005/08/27(土) 15:09:57
>>852
変数を使ったコードで命令と一緒にパラメタとして使われてる。
854デフォルトの名無しさん:2005/08/27(土) 18:32:46
なんでアドレスを格納するのにポインタって型が必要なの?
855デフォルトの名無しさん:2005/08/27(土) 18:51:56
>>854
別にポインタって型が必要といわけでは無いのだが、
ポインタって型がないとポインタと単なる整数の区別がつかなくてさらにバグを生み出す原因に
856デフォルトの名無しさん:2005/08/27(土) 18:55:30
>>854
大量のデータが必要でも、動的に確保できるので、実行時に使用するメモリを減らせる。
また、サイズの変更が容易になる。

大量のデータでもアドレス計算を少なくして処理できる。

アドレスを単純に増加させてもオフセットの取り方で連続したメモリにならない。
その境界部分の演算が遅くなる原因になるがポインタを使えば境界を越える演算が減らせる。

コード記述で、名前に依存しない記述が可能になる。
同じ関数内で少ないコードで多彩な動作が可能になる。

こんなところだと思う。
857856:2005/08/27(土) 18:57:07
>>855
あ、そうそう。そうだ。

MSのファイルポインタとか全然ポインタじゃないのにポインタとか・・・
858デフォルトの名無しさん:2005/08/29(月) 08:45:50
unsigned long ときたらアドレスと思うよーに!
859デフォルトの名無しさん:2005/08/29(月) 08:57:19
あとは型付けな。
勝手に型をつけてくるのは、場合によっては邪魔になることもあるが。
860デフォルトの名無しさん:2005/08/29(月) 16:44:00
ポインタを解りずらくさせてる要因ってなんだ?
861デフォルトの名無しさん:2005/08/29(月) 16:47:54
使う機会が少ないから熟練しない
862デフォルトの名無しさん:2005/08/29(月) 16:53:46
>>861
いや、画像処理とかで使いまくりなんだが
863デフォルトの名無しさん:2005/08/29(月) 19:17:52
「ポインタは難しい」っていう先入観と、
解説する人間の数だけ増えるポインタの例え方

クラスにも通じる物がありますね
864デフォルトの名無しさん:2005/08/29(月) 21:19:27
クラスって「オブジェクト指向」って言葉を使うから悪いんじゃね?
「オブジェクト指向」って言葉には殆ど意味なんてないし。
OOAとかOOPとか、後に何か付いてやっと意味になる。
865デフォルトの名無しさん:2005/08/29(月) 21:47:03
>858
32bit用コンパイラでもポインタのサイズ全部が32bitだと思ったら大変危険。

>860
C言語の仕様だとおもう。


866デフォルトの名無しさん:2005/08/30(火) 09:55:15
>>865
Linuxは全部こうなんだけど、そろそろどうなんだろうね
867デフォルトの名無しさん:2005/08/30(火) 16:31:57
>>858
そんなソースコードいやぽ(;´Д`)
868デフォルトの名無しさん:2005/08/30(火) 16:37:13
>>867
しょうがないよ
マジだもん
869デフォルトの名無しさん:2005/08/30(火) 17:16:25
せめてuintptr_t
870デフォルトの名無しさん:2005/08/30(火) 18:59:49
>>866
Linuxの何が「こう」なの?
871デフォルトの名無しさん:2005/08/30(火) 19:09:29
UNIXにはポインタをint扱いするプログラムがいまだに溢れてる
872デフォルトの名無しさん:2005/08/30(火) 19:48:14
>>870
ポインタとかアドレスを unsigned long と扱うコード
873デフォルトの名無しさん:2005/08/30(火) 20:42:24
>>871-872
なんでそんなことになってんの?
メリットは何?

874デフォルトの名無しさん:2005/08/30(火) 20:52:05
>>873
今となってはもはや昔ながらの伝統以外の意味は全くない
875デフォルトの名無しさん:2005/08/31(水) 16:54:40
>>872
全部ってこたねえだろう。
876デフォルトの名無しさん:2005/09/25(日) 02:53:10
ポインタってどういう場面で使用されるんですか?
877デフォルトの名無しさん:2005/09/25(日) 09:58:37
878デフォルトの名無しさん:2005/10/01(土) 21:46:45
ポインタを多用するプログラムってどんなのがあるのでしょうか
879デフォルトの名無しさん:2005/10/01(土) 21:48:49
Windows プログラム
880デフォルトの名無しさん:2005/10/02(日) 15:41:45
Lisp処理系
881デフォルトの名無しさん:2005/10/04(火) 12:52:03
ポインタ〜ッチ。いやぁ〜ん,まいっちんぐ。
882デフォルトの名無しさん:2005/10/07(金) 01:18:25
まだこのスレあったのね。
ポインタはね、関数で複数の戻り値を返したい時にとても便利なんだお。
普通はreturnで一個しか返せないんだお。
883デフォルトの名無しさん:2005/10/07(金) 18:28:57
>>882
構造体
884デフォルトの名無しさん:2005/10/08(土) 09:43:23
>>883
戻り値は構造体のポインタであって
構造体そのものではない罠
885デフォルトの名無しさん:2005/10/08(土) 09:51:21
構造体を返して何が悪い。
886デフォルトの名無しさん:2005/10/08(土) 12:09:06
>>885
構造体は返せない。
構造体のポインタは返せるが。

構造体と構造体のポインタは別物。
887デフォルトの名無しさん:2005/10/08(土) 12:16:30
そういうこと言ってるから、陰で時代錯誤の老害って言われるんだよ
888デフォルトの名無しさん:2005/10/08(土) 12:19:06
事実なんだけど…

嘘教えるより100倍マシだと思うけど…
889デフォルトの名無しさん:2005/10/08(土) 12:19:27
構造体返せるだろ?
890デフォルトの名無しさん:2005/10/08(土) 12:20:27
つい最近返せるようになった。
891デフォルトの名無しさん:2005/10/08(土) 12:20:48
>>889
構造体を返すプログラムのソース挙げて見れ。
892デフォルトの名無しさん:2005/10/08(土) 12:20:57
つい最近?
893デフォルトの名無しさん:2005/10/08(土) 12:23:29
typedef struct {
int a,b,c,d;
} E;

E foo(E ee){
return ee;
}

894デフォルトの名無しさん:2005/10/08(土) 12:27:18
ANSIで標準化された1989年の時点で
構造体は返せるし渡せるようになっているんだけど

> 嘘教えるより100倍マシだと思うけど…
などと言いながら、平気でウソを教える。
だから「老害」なんだよ。
895デフォルトの名無しさん:2005/10/08(土) 13:03:15
標準関数にもdivとか構造体を返す関数がある。
896デフォルトの名無しさん:2005/10/11(火) 02:43:49
構造体が大きいとスタックに積む時間が何だかアレな気はする
897デフォルトの名無しさん:2005/10/11(火) 02:58:09
まあ、構造体を返す関数の場合は、
一般的な実装では、暗黙の第一引数として呼び出し側がアドレスを渡して
そこに代入するんだけどな。
あと、レジスタで渡せるサイズだったらレジスタで返す実装もあった。

もちろん、渡す場合は全コピーだけど。
898デフォルトの名無しさん:2005/10/11(火) 03:38:37
その昔、異様に大きな配列メンバを持つ構造体を定義して、
実体を返してみたら、実行速度が物凄く遅くなってワロタ。
Cでも配列を実体で返せる方法だと、馬鹿そのものの歓び方をした。
899デフォルトの名無しさん:2005/10/11(火) 11:55:04
かって知ったる構造体なら値渡しでもいいがな。
900デフォルトの名無しさん:2005/10/11(火) 19:25:37
気分的に32byte超えると悪いことしてる気がしてしまう
いや、なんとなく
901デフォルトの名無しさん:2005/10/11(火) 19:43:46
まあ俺は32bit超えると悪いことしてる気がするが。
902デフォルトの名無しさん:2005/10/11(火) 19:50:43
>>901
そりゃ大変だな…
903デフォルトの名無しさん:2005/10/12(水) 02:57:01
つまりグローバル変数しか使わないってことかい?
904デフォルトの名無しさん:2005/10/12(水) 03:54:54
ポインタを返すんだろ
905デフォルトの名無しさん:2005/10/12(水) 04:15:24
1byteじゃなくて32bitに限定しているから、64bitアプリでは破綻。
しかし16bitアプリでは二つのポインタが!!
906デフォルトの名無しさん:2005/10/12(水) 04:19:41
二つのボイン
907デフォルトの名無しさん:2005/10/12(水) 08:28:08
64bitアプリでも今の規格ではポインタは32bitだよなぁ確か。
908デフォルトの名無しさん:2005/10/12(水) 16:28:10

寝言は寝て言え
909デフォルトの名無しさん:2005/10/17(月) 04:07:53
mixi でも糞壁って猛威を振るってんだな。
int* p; でも int *p; でも好きにすりゃええやん。
910デフォルトの名無しさん:2005/10/18(火) 19:37:20
>>894
ANSI 以前の C でも構造体は返せるようになっていた。
しかしその後流行出したPCでのCコンパイラの実装では
使えないようになっているサブセットのやつが多かった。
実際使うと恐ろしく遅くなることがあって、使えても
使う人は少なかったのではないかと思う。
911デフォルトの名無しさん:2005/10/18(火) 21:00:35
構造体を返す変数・・・fopenとか?
912デフォルトの名無しさん:2005/10/18(火) 21:01:30
変数じゃねぇな関数だ(´Д`;)
913デフォルトの名無しさん:2005/10/18(火) 21:15:56
fopenが返すのはポインタだが
914デフォルトの名無しさん:2005/10/18(火) 21:46:57
915デフォルトの名無しさん:2005/10/18(火) 22:43:05
>>911 → >>913 → >>1
以下ループ
916デフォルトの名無しさん:2005/10/19(水) 08:37:19
巨大な構造体返す関数書くと戻り値を、コピーせずに
呼び出し側のスタックに直接書き込む言語もあったりするな。
917デフォルトの名無しさん
>>916
最適化具合でそうなるコンパイラもありえるんじゃね?