C言語のポインタってなんですか?
レス数が900を超えています。1000を超えると表示できなくなるよ。
0001デフォルトの名無しさん
NGNG0002デフォルトの名無しさん
NGNG0003デフォルトの名無しさん
NGNG0004デフォルトの名無しさん
NGNG0005デフォルトの名無しさん
NGNGコピペ断固反対
0006デフォルトの名無しさん
NGNG0008デフォルトの名無しさん
NGNGマルチポスト断固反対
0009デフォルトの名無しさん
NGNG0010デフォルトの名無しさん
NGNGマルチ厨。
やっぱスレ立てやがった。
C言語のポインタってなんですか?
http://pc3.2ch.net/test/read.cgi/pc/1056082601/l50
00111
NGNG0012デフォルトの名無しさん
NGNG00131
NGNG0014デフォルトの名無しさん
NGNG0015デフォルトの名無しさん
NGNG>あらゆる質問はまずすれ立てるまでもない質問はここでスレにしてください。
00161
NGNG0017デフォルトの名無しさん
NGNGいいよ、いいよぉ〜
0018山崎 渉
NGNG__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0019山崎 渉
NGNG__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0020山崎 渉
NGNG0021山崎 渉
NGNG│ ^ ^ │<これからも僕を応援して下さいね(^^)。
⊂| |つ
(_)(_) 山崎パン
0022デフォルトの名無しさん
NGNG0023デフォルトの名無しさん
NGNG0024デフォルトの名無しさん
NGNG21世紀のメイド型ロボットの総称。
0025デフォルトの名無しさん
NGNG0026デフォルトの名無しさん
NGNG仕様です
0027デフォルトの名無しさん
NGNG0028デフォルトの名無しさん
NGNG0029デフォルトの名無しさん
NGNG0030デフォルトの名無しさん
NGNG理論は後からついてくる。
まず最初に覚えるべきポインタの利用方法は、関数の引数への代入。
関数は引数に入力、返値に出力という構造が基本だが、これだと出力は一つしか持てない。
そこで本来入力としての引数にポインタを使えば、引数も出力として扱うことができる。
なぜそうなるのか?という疑問を持ったなら、調べてみるといい。
アドレス渡しと値渡しの違いが分かれば、ポインタの仕組みが理解できてくるだろう。
0031デフォルトの名無しさん
NGNG0032デフォルトの名無しさん
NGNG0033デフォルトの名無しさん
NGNGメールアドレス教えてお金渡してもらう
0034デフォルトの名無しさん
NGNGそれとあと構造体でみんな挫折するそうです。
0035デフォルトの名無しさん
NGNGそういうのが出てくると死ねるそうです。
0036デフォルトの名無しさん
NGNG理解することは有益だろうか?
0037デフォルトの名無しさん
NGNGに、行け
0038デフォルトの名無しさん
NGNGアセンブラから覚えろ
そしたらこんなアホな質問はなくなる
0039デフォルトの名無しさん
NGNG鼻から飲め
そしたらいざというとき口から出せる
0040デフォルトの名無しさん
NGNG0041デフォルトの名無しさん
NGNGC の関数は全て値渡しに過ぎない。
ポインタ値と言う値を渡すだけ。
0042デフォルトの名無しさん
NGNG0043デフォルトの名無しさん
NGNGttp://pc2.2ch.net/test/read.cgi/tech/1030901827/
終了
0044デフォルトの名無しさん
NGNGって、本に書いてあったから、真似して言ってみたかったんだろ?
もう一度>>30を読み返せ。っていっても、オマエには理解不能か(w
>>43
終了させたいならあげるなよ。
0045supermathmania ◆ViEu89Okng
NGNG0046デフォルトの名無しさん
NGNG0047デフォルトの名無しさん
NGNG0048デフォルトの名無しさん
NGNGはポインタですよ。
0049デフォルトの名無しさん
NGNGだからガッってやられるんですね。
0050デフォルトの名無しさん
NGNGgj台追いf;亜jんhきgf;あきgふぁhにごれ
0051デフォルトの名無しさん
NGNG0052デフォルトの名無しさん
NGNGなんで、Javaにポインタはないんですか?
0053デフォルトの名無しさん
NGNGぬーんC言語が糞だからだよ
るるるむしろC言語のポインタが糞だと言ったほうがいい
ぽっぽーつまり要するにC言語のポインタはポインタと自称しているわりに余計な機能が付きすぎてるってこった
だからJava様はそんなヘポインタと一緒にされたくなかったわけなのです
0054デフォルトの名無しさん
NGNGポインタはあるんだけどポインタと言いがたい状況だ。
アドレスを参照する具合な感じだからポインタを扱ってる用に見えないだけではないのかな?
0055デフォルトの名無しさん
NGNGアセンブラから入った人は素直にアドレス型だとわかる。
アセンブラやらない今の人は、ポインタ型=クラスだと
思い込みがちだが、全然違うもの。構造体へのポインタ型
と代入操作に対する扱いにくさは似ていなくも無いが。
0056デフォルトの名無しさん
NGNG経験が物をいうんじゃないか?
いくべんも失敗して理解しる
0057デフォルトの名無しさん
NGNGint型のポインタ型とかchar型のポイント型とかあって
わけわかんねーよ!
アセンブラのほうがよっぽど素直だ
0058デフォルトの名無しさん
NGNG指し示す先の位置の他に、指し示す先がどんな種類のデータか?と言う情報があるだけじゃん。
0059デフォルトの名無しさん
NGNGじゃあアセンブラしてください。
int型のポインタ型は変
int型のポインタとは言うがポインタ型っておかしくないか?
ポインタは型では無いのでわけわかめにはなりません
0060デフォルトの名無しさん
NGNG0061デフォルトの名無しさん
NGNGそういう風に言うならば long型 じゃね?
0062デフォルトの名無しさん
NGNG>ポインタは型では無いのでわけわかめにはなりません
ポインタ型は存在する訳で(ry
0063デフォルトの名無しさん
NGNG略してないよ全然w
あぃ、あるんですね。
わかりました
0064デフォルトの名無しさん
NGNGint a,b,c,…;
*(p+0) = &a;
*(p+1) = &b;
*(p+2) = &c;
…
これ、領域も確保してなくとも*(p+n)には代入していけるのですか?
0065デフォルトの名無しさん
NGNG006665
NGNG面倒くさいので全部 int で逝きます
a
□ int型 a です
*p a
□─→□
int型をさすポインタも変数であるわけね
**pp *p a
□─→□─→□
**になると int型をさすポインタをさすポインタ になります。
で、>>64だと *p が何処にあるか指定されて無いから代入できないわけ
代入できても暴走する可能性がある
0067デフォルトの名無しさん
NGNGどこか有効な領域を指していれば出来る。
# 意図したものとは恐ろしく違うだろうがな。(w
0068デフォルトの名無しさん
NGNG出来るかも知れないけどさぁ・・・やばくないかなぁ〜^^;
006964
NGNGp = (int **)malloc(sizeof(int *))
p = &a[0];
p+1 = (int **)malloc(sizeof(int *))
p+1 = &b[0];
これで良いですか?
0070デフォルトの名無しさん
NGNG自分でやってみたら?
0071デフォルトの名無しさん
NGNGめちゃくちゃ.
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....は滅茶苦茶
でコンパイルも通らない筈(アドレス値は左辺値にならない)
0072デフォルトの名無しさん
NGNG解ることは>>71の文章に無駄が多いという事でした
0073デフォルトの名無しさん
NGNG0074デフォルトの名無しさん
NGNGC言語のポインタは垂らす調味料なので、少量しか食べられません。
たくさん食べると体調不良になります。
0075デフォルトの名無しさん
NGNGまさにその通りだけど、初心者にはわけわからんと思われ。
007664
NGNGまた明日レスします。
0077デフォルトの名無しさん
NGNG無理に背伸びしなくていい
簡単に言うと
「出来るか」「出来ないか」だろ?
>>64の疑問は「出来ない」の方、解決法を見出せばわからなかったことが解るかもしてないぜ
0078デフォルトの名無しさん
NGNGchar 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でデータを入れるのに要するメモリ数が異なるためこれは実行できない。
007978
NGNGint 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です。
008079
NGNGmallocはイメージとしてはメモリ内に固定領域をプログラマが任意に取ることができます。
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));
であり、論理的には問題ないと思います。
しかし、現実にはこのように何が入っているかわからないような危険な事は避けた方が良いでしょう。
0081デフォルトの名無しさん
NGNG008280
NGNGちなみに
*pointer;
pointer = (*int)malloc(sizeof(int));
の(*int)はキャスト演算子です。
キャスト演算子とは右辺の値をキャスト(変換)して左辺に代入します。
int n = 0;
float f = 1.5;
n = (int)f;
としますと、floatで表された浮動小数点が小数点以下で切り捨てられ
n == 1 となります。
あとは構造体の説明が終われば>>69さんもばっちりですね。
008381
NGNG構造体について。
構造体とはイメージとしてユーザー定義の変数の型です。
struct おいらが自由に作る型 rei{
char name;
int age;
char address[50];
struct おいらが自由に作る型 *free;
};
今まで利用していたint型やchar型というのはC言語側が勝手に作った型で使い勝手が悪い事があります。
例えば、double以上の精度の浮動少数(バイト数が多いほど高精度)を扱いたい場合や、違う型を複数持つ多次元配列などです。
そういう時に「既存の型を組み合わせて自分の好きな型を作れれば・・・」という期待に答え(?)
構造体が実現されています。
上記の例は複数人いる人のデータを入れる変数の型に使えますよね。
ポインタを使う場合も今までのポインタ変数と同じく、
struct 自分で作った型 *pointerとしてその構造体の位置を示すポインタを入れる変数を作る事ができます。
また、構造体では既存の型のように
struct おいらが自由に作る型 任意の変数名
でいくらでも同じ型の変数を作る事ができます。
なお、構造体の中の自分の型と同じポインタは簡単に説明すると、「リスト構造」などを利用する際、構造体の中で自分と同じ構造の
ポインタを使うと色々便利なことができるのです。(詳細は別途調べてね♪)
008483
NGNG・・・
・・・
・・・
ごめんなさい、飽きました。
間違っていたら本職のプログラマさん訂正してやってください。
学生さんは学校の卒業制作で忙しいのでJava初心者スレに戻ります。
じゃね。
008564
NGNG#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;
008664
NGNG*(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
008864
NGNGchar ***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] ]
008964
NGNGindex_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;
009064
NGNGp = (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;
009164
NGNGprintf("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;
}
009264
NGNGgroup:0
str_a group0
str_f group0
str_c group0,1
group:1
str_b group1
str_c group0,1
str_g group1
009464
NGNGこのように宣言した場合、
&p番地に(char ***)型のp領域が生成される。
しかし、&(p+1)番地に(char ***)型のp+1領域は生成されない。
ょってpは左辺値になり、p+1は左辺値にならない。
p+1,p+2等は連続性のある領域確保(配列、calloc)の時だけ存在する。その並びを進んでいくから。
その歩幅は、(char **)*p領域を刺すのであれば、(char **)分だけ進む事となる。
このような理解で間違えていないでしょうか。アドバイスして頂けると有りがたいです。
009564
NGNG0096デフォルトの名無しさん
NGNG>char ***p;
>このように宣言した場合、
>&p番地に(char ***)型のp領域が生成される。
&p番地って? おかしな解釈はやめたほうがいいぞ。ちゃんと初心者用の入門書を買って読め。
あと、何も「生成」はされないぞ。
009764
NGNG> &p番地って? 何も「生成」はされないぞ。
記憶領域が生成されるから、そこへアドレスを代入できるのでは,ないでしょうか?
p = malloc(char);
0098デフォルトの名無しさん
NGNG20%くらい還元してくれたらうれしいな。
それとどこの店でもポインタは使えますか。
ゴールドポインタカードって誰でも作ることできますか。
0099デフォルトの名無しさん
NGNG○ ある領域が(char***型の)pの為に割り当てられる
? しかし、&(p+1)番地に(char ***)型のp+1領域は生成されない。
あまりにも当たり前というか関係が無さ過ぎ。
まるで「今日ラーメンを食べても明日は晴れになるとは限らない」とでも書かれてるようだ。
わざわざこんな事を表明したり確認したりするのは勘違いの種が植えられている証拠。
? p+1,p+2等は連続性のある領域確保(配列、calloc)の時だけ存在する。
もっとシンプルに考えるべき。ポインタがするのはあるオブジェクトを指し示す事だけ。
領域が確保されているかどうかは別の話。
? その歩幅は、(char **)*p領域を刺すのであれば、(char **)分だけ進む事となる。
何が言いたいのかこの文章からだと正確に意味を汲み取れない。
コミュニケイションは大事なので表記法には気をつけましょう。
char***型の変数に+1するとsizeof(char**)の分だけ値が増えると言いたいのでしょうか?
010064
NGNGp+1の確認について:
私の書きこみ>>69にて、p+1 を左辺値として誤用してしまい、
それに対して>>71等からアドバイスして貰いました。
そういう事が以前にあってp+1の事についての考えを書きました。
010188
NGNG>もっとシンプルに考えるべき。ポインタがするのはあるオブジェクトを指し示す事だけ。
>領域が確保されているかどうかは別の話。
領域確保とポインタは別の話ですね。
010288
NGNG> char***型の変数に+1するとsizeof(char**)の分だけ値が増えると言いたいのでしょうか?
その事が言いたかったのです。「(char **)*p」というのは、char**型の*pという事を示したかった
のです。キャストで書いておけば、変数名とその型の2つを表現できると思ったので。
このような表記法は、伝わりにくいですね。気を付けます。
0103デフォルトの名無しさん
NGNGfor(i=0; i<sizeof n; i++)
i[n] = 0;
のようなコードを書いて新人を混乱させるのが僕の唯一の楽しみです。
0104デフォルトの名無しさん
NGNGそれで混乱させれるの?
0105デフォルトの名無しさん
NGNG0106デフォルトの名無しさん
NGNGヒネルにしてももう少し知的なコードの方が。
0107デフォルトの名無しさん
NGNGi<sizof n
って、君配列を勉強しなおしなさい!
0108デフォルトの名無しさん
NGNG0109デフォルトの名無しさん
NGNG0110デフォルトの名無しさん
NGNGn[i]==*(n+i)==*(i+n)==i[n]
0111デフォルトの名無しさん
NGNG0112デフォルトの名無しさん
NGNGすごい、こんな使い方初めてしりました。感動です
0113デフォルトの名無しさん
NGNG0114デフォルトの名無しさん
NGNGsizeof は予約語だから()いらないよ
0115デフォルトの名無しさん
NGNGsizeofのことか?括弧が必要なのは型のサイズを知りたいとき。つーか型の時はキャスト式だから括弧が必要なだけ。
0116デフォルトの名無しさん
NGNG0117デフォルトの名無しさん
NGNGそりゃ混乱するわ。
i < sizeof n / sizeof n[0]
0118デフォルトの名無しさん
NGNGなにゆってる?
0119デフォルトの名無しさん
NGNG0120デフォルトの名無しさん
NGNGそう決まっているわけじゃないから、やっぱりダメ。
0121デフォルトの名無しさん
NGNG0122デフォルトの名無しさん
NGNG0123デフォルトの名無しさん
NGNG0124デフォルトの名無しさん
NGNG0125デフォルトの名無しさん
NGNG0126デフォルトの名無しさん
NGNG0127デフォルトの名無しさん
NGNG0128デフォルトの名無しさん
NGNG0129デフォルトの名無しさん
NGNG{
int i;
for(i=0; i<sizeof n; i++)
i[n] = 0;
}
のようなコードを書いて新人を混乱させるのが僕の唯一の楽しみです。
0130デフォルトの名無しさん
NGNGノ\_・’ヽO.←>>128
└ _ノ ヽ
〉
0131デフォルトの名無しさん
NGNGそのポインタのポインタをポインタのポインタに
ポインタのポインタのポインタとしてコピー
0132デフォルトの名無しさん
NGNG0133デフォルトの名無しさん
NGNG0134デフォルトの名無しさん
NGNG0135デフォルトの名無しさん
NGNG0136デフォルトの名無しさん
NGNGそのままじゃん
void (**pf)(void);
0137デフォルトの名無しさん
NGNG0138デフォルトの名無しさん
NGNG0139デフォルトの名無しさん
NGNGそれ配列です。
0140デフォルトの名無しさん
NGNG0141デフォルトの名無しさん
NGNG0142デフォルトの名無しさん
NGNG0143デフォルトの名無しさん
NGNG一生ぼいんたんと遊んでろ
0144デフォルトの名無しさん
NGNGint*pA = &A;
int**ppA = &pA;
int***pppA = &ppA;
int****ppppA = &pppA;
0145デフォルトの名無しさん
NGNGわかりやすいサンプルですね
0146デフォルトの名無しさん
NGNG使い方をあまり知らないから「ね、ポインタって
難しいでしょ?」と言われると納得してしまいます。
ポインタだけが難しいという勘違いをするわけです。
未知の事なんて何でもかんでも難しいし、慣れない
テクニックを利用するのはややこしいものなんです。
だれか先人の中にポインタで極端に苦労した人がいたんでしょう。
0147デフォルトの名無しさん
NGNGあなたみたいな人です
0148デフォルトの名無しさん
NGNG0149デフォルトの名無しさん
NGNG数学の数列が難しいというやつとかと似てる
0150デフォルトの名無しさん
NGNGint &rA = A;
int *pA = &A;
int *&rpA = pA;
0151デフォルトの名無しさん
NGNGそのときポインタといえばインデックスレジスタを指すていう
前提でやってたから、C言語のポインタはなんか違和感があって
すんなり使えなかったです。
0152でません
NGNGんーーーー
んーーーー
#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]);
}
0153152
NGNGポインタの指す、文字列のあるアドレス
*WeekName(week) で参照できるのは、
ポインタの指す、文字列の先頭一文字のデータ
printf関数の%s変換は最初からポインタを引数にするようになっているので
アドレスを指すポインタを引数に与えると、
そのアドレスにある文字列が表示される。
他は、なんか値があるけど、関係ないので、この際気にしない。
unsigned intの値を表示するための
printf関数の変換指定文字は%dでなくて%uでした。
たまたま負の値が出なかったので、警告されなかったようです。
ポインタ専用の%pというのもあるようです。
汚しまして失礼。
それでは、ばかは、ちょっとだけ出たので、寝ます。
0154デフォルトの名無しさん
NGNG*WeekName:(%d)(%d), *WeekName(week):(%d)(%d) \
WeekName:(%d)(%d), WeekName(week):(%d)(%d)\n"
0155デフォルトの名無しさん
NGNG0156デフォルトの名無しさん
NGNG(1) int *a;
(2) int* a;
0157デフォルトの名無しさん
NGNG(1) int *a, *b;
(2) int* a, b;
0158デフォルトの名無しさん
NGNGその1と2は意味が違うぞ。
0159デフォルトの名無しさん
NGNG(1)(´Д⊂ヽ
(2)(つД`)
0160デフォルトの名無しさん
NGNG0161945
NGNG0162デフォルトの名無しさん
NGNG関数の戻り値にポインタがあった場合は(2)、通常は(1)
int* CreateInt()
{
int *p = malloc (sizeof int);
return p;
}
といった感じ
0163デフォルトの名無しさん
NGNGint* foo(void),* bar(void);
並べるやつがわるいのか?
0164デフォルトの名無しさん
NGNGそいつは氏んだほうがいい
0165デフォルトの名無しさん
NGNG0166デフォルトの名無しさん
NGNGint*型のaを宣言しているのであって、int型の*aを宣言しているわけではないと言う
意味合いからは(2)。
>>157
間違いを起こさないためには(1)。
と言うのを天秤にかけ、ポリシーよりも安全性を選ぶ俺は(1)。
0167デフォルトの名無しさん
NGNG一貫性の欠如
0168デフォルトの名無しさん
NGNG仮引数の時だけint* a;にしてる
0169デフォルトの名無しさん
NGNG0170デフォルトの名無しさん
NGNGで混乱するのはCに不慣れな初心者だけだろ。
0171デフォルトの名無しさん
NGNGなんてやるのもね。
0172デフォルトの名無しさん
NGNG>で混乱するのはCに不慣れな初心者だけだろ。
で混乱するのはおかしくない?
むしろ
>int* a,b;
>なんてやるのもね。
コレはかなり禁止だろう。
見た目悪すぎ
0173デフォルトの名無しさん
NGNG初心者にポインタを分かりにくくしている原因の一つかもね。
int* a;
しか許されてなかったら、初期化してないポインタに対していきなり代入
*a=0;
という誤解は減ったかも。
0174デフォルトの名無しさん
NGNGという表記は考え方としては間違ってはいないが
実際にコードとして書くのは(文法的には正しいとしても)明らかに間違い。
なぜなら
int* a, b
が期待した挙動を示さないから。ゆえにどんな場合でも
int *a
と書くべき。ケースによって
int* a
int *a
を使い分けるメリットは皆無。逆に表記の一貫性を損なうというデメリットしかない。
C言語はセンスの捻じ曲がった人間が開発した以上(素人の)常識は通用しない。郷に従うのが筋。
これに反論する奴は
#define BEGIN {
#define END }
とかやってる奴と同類。
0175デフォルトの名無しさん
NGNG>>162の考え方はどうでしょうか?
0176デフォルトの名無しさん
NGNGもしかしてアセンブラ命令の
LAD GR1,A
とかそんな感じの事でしょうか?
確かにポインタと酷似してるんですが・・・
0177デフォルトの名無しさん
NGNG大体いろんなアセンブリ言語あるし。
アドレスとかデータとか、間接アドレッシングだとかラベルだとか、
その辺使ってれば容易にポインタなど理解できると言う意味では?
0178デフォルトの名無しさん
NGNGだまされてるだまされてる
0180デフォルトの名無しさん
NGNGint *a
という表記は考え方としては間違ってはいないが
実際にコードとして書くのは(文法的には正しいとしても)明らかに間違い。
なぜなら
int *a, b
が期待した挙動を示さないから。ゆえにどんな場合でも
int *a もしくは int* a
と書くべき。ケースによって
int* a
int *a
を使い分けるメリットは皆無。逆に表記の一貫性を損なうというデメリットしかない。
C言語はセンスの捻じ曲がった人間が開発した以上(素人の)常識は通用しない。郷に従うのが筋。
これに反論する奴は
#define BEGIN {
#define END }
とかやってる奴と同類。
0181175
NGNGがもう一回出してくるから良く読んでみたら
最後の方は理論が通ってるが前半は合わないや
int* a;
これは邪悪なのでやめたほうがいい
int* a, b;
*がどちらへかかってるのかわかりづらい
int *a, b;
とやって a がポインタである事を明示的に示すべき
int *a;
int b;
とやるべきでもあるかも知れない
0182デフォルトの名無しさん
NGNG初心者の混乱も少なくて済んだのにね
0183デフォルトの名無しさん
NGNGhoge* hoge;
0184デフォルトの名無しさん
NGNGいやー、論旨をひっくり返そうとしたけど失敗したんだよ。
気にしないで。
0185140
NGNGint *p; Cプログラマーに多い。要するに古い。
int* p,n; コレの意味が同型だと理解するようなやつは一から勉強しなおせと言いなくなる
で結論は最初はスタイルなど気にせずわかりやすい意味のある変数名、関数名などでプログラムを
組んでいくほうが後々のためだと思うのだが。エレガントなプログラムなんて後からついてくるもの。
と、俺は考える。
0186デフォルトの名無しさん
NGNGtypedef int *pint;
pint p,n;
0187デフォルトの名無しさん
NGNGゆえに
int *a;
int* a;
どっちでもいい、と考えてみる 1変数宣言派はいないかなぁ。
0188初心者
NGNGなんで気付かなかったんだろ?
0189デフォルトの名無しさん
NGNG0190175
NGNG>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は違うので、変数ごとに解りやすくやったほうがいいわけ
0191デフォルトの名無しさん
NGNGハァ?
0192デフォルトの名無しさん
NGNG0193デフォルトの名無しさん
NGNG0194デフォルトの名無しさん
NGNGあつてるだろ。参照はほとんどそれ。
0195デフォルトの名無しさん
NGNG0196デフォルトの名無しさん
NGNG妄想はいいから
>>int* n; C++的。
の根拠を示せ。
& じゃなくて * のな。
0197デフォルトの名無しさん
NGNG書き方に こだわりすぎると
他人のソースも ろくに読めなくなるんじゃね?
0198デフォルトの名無しさん
NGNG>>183
0200デフォルトの名無しさん
NGNG0201デフォルトの名無しさん
NGNG0202デフォルトの名無しさん
NGNG0203デフォルトの名無しさん
NGNG0204デフォルトの名無しさん
NGNG0205デフォルトの名無しさん
NGNG0206デフォルトの名無しさん
NGNGそういや、そうだなぁ。
今度 C++で
int* a;
の表記をしようと思っていたがやめた方が吉なのか。
この板でそういう記述の人がいて、みてみると
なるほど、その方が合理的だよなぁと思ったんだが
int* a, b; で b がポインタにならないのであれば
誤解を与えやすいな。
0207デフォルトの名無しさん
NGNGポインタは考え方よりも実際のコード(表記)で混乱することが多い。
K&Rにもよく理解できない複雑な事例が載っていたなぁ・・・
この辺を極める本ってあります?
K&Rはちと説明が簡素すぎてよく理解できなかったんだ。
0208デフォルトの名無しさん
NGNGじゃあ int* p, n; とすりゃいい。
0209デフォルトの名無しさん
NGNGいま私の願いごとが かなうならば翼がほしい この背中に鳥のように 白い翼つけてください
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ行きたい
いま富とか名誉ならば いらないけど翼がほしい 子どものとき夢みたこと 今も同じ夢に見ている
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ
この大空に翼をひろげ 飛んで行きたいよ 悲しみのない自由な空へ 翼はためかせ 行きたい
0210デフォルトの名無しさん
NGNGいまだにそんなこといってるのか?
・1行に複数の変数を宣言/定義しない。
・変数を定義するときは可能なかぎり初期化する。
というのが、いまどき普通だろ。
0211デフォルトの名無しさん
NGNG俺はプロじゃないんで、よく分からんのですが
そういうもんですか。
0212デフォルトの名無しさん
NGNGint *p, n;
単独の場合はint* p;にしている
一貫性がないが、場合分けの基準は一貫しているので問題ない。
0213デフォルトの名無しさん
NGNG減らしたくなったりしないのか?
0214デフォルトの名無しさん
NGNG0215新人
NGNGだよ〜
0216デフォルトの名無しさん
NGNG秘伝C言語問答 ポインタ編 柴田望洋
0217デフォルトの名無しさん
NGNGint a; // コメント
int b; // コメント
見たいな書き方が多い。i,j等のループに使うどうでもいい変数だけは
羅列することが多い。ポインタの場合、どうでもいいポインタって俺の使い
方ではほとんど無いから羅列したことは無い。
そんな俺は
int* a;
と宣言する派。
0218デフォルトの名無しさん
NGNGあぁ、専門学校だろ?
専門学校はコメントを良く書けといわれるらしいな
0219デフォルトの名無しさん
NGNG0220デフォルトの名無しさん
NGNG0221デフォルトの名無しさん
NGNGうん、そうみたいね。
俺も通ってるわけじゃないから詳しい事は解らないけど
聞いた話によると就職にコメントが詳しく書いてあると有利らしい
ときどきは間違ったプログラム、つまり期待してた動作をしなくても入社できるらしい
0222デフォルトの名無しさん
NGNGそんなことしたら変数名の意味がなくなるし。
0223デフォルトの名無しさん
NGNGつまり
int comment_count;
char comment_str;
とかにするって事?
とボケてみたけどレベルいくつでしょう?
0224デフォルトの名無しさん
NGNGってゆーか
int loopCounter_1_to_10_forUse_arrayTbl;
char *errorMessage_pointer_for_get_functionReturnStatus;
とかなら俺は嫌。
もっとも
int l; /* arrayTbl[]用に1から10の値で使うループカウンタ */
char *m; /* 関数を呼び出した際、エラーメッセージを受け取るポインタ */
とかだとさらに嫌
0225デフォルトの名無しさん
NGNGttp://www.tetish.com/english%20pointer.htm
0226デフォルトの名無しさん
NGNGループだけに使う変数は、柿のように使うのはどうでしょうか?
…
{int a; for(a…){
}}
…
0227デフォルトの名無しさん
NGNGint* const a;
int *const a;
int*const a;
どれが好み?
0228デフォルトの名無しさん
NGNGCPINT a;
0229デフォルトの名無しさん
NGNG0230デフォルトの名無しさん
NGNGそれやったらやっぱbはポインタじゃなくなるんですか?
0231デフォルトの名無しさん
NGNG0232デフォルトの名無しさん
NGNGいいえ。
typedefじゃないもん。
0233デフォルトの名無しさん
NGNGこんなんはじめて見た。
ポインタの中身じゃなくて、ポインタそのものの値が固定になるのか?
0234デフォルトの名無しさん
NGNG判定条件の変数にちゃんと名前が付いてれば何のループかすぐわかるじゃん。
ループ変数だと一目でわかんない名前の方がもっとイヤ
0235デフォルトの名無しさん
NGNGその通りだ。因みに
const int * a
int const * a;
この二つは、同じだ。
0236デフォルトの名無しさん
NGNG0237デフォルトの名無しさん
NGNG#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 と出力できる?
0238デフォルトの名無しさん
NGNG0239デフォルトの名無しさん
NGNGvoid 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);
}
うちの環境だとこれでいけた。
0240デフォルトの名無しさん
NGNGchar *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;
だった。
でも、できるのかなあ?
0241デフォルトの名無しさん
NGNGint が 32bit なら
int txt =a<<24 | b<<16 | c<<8 | d;
↓
int txt = ntoh(a<<24 | b<<16 | c<<8 | d);
で出来るだろう。
0242デフォルトの名無しさん
NGNG× ntoh
○ ntohl
0243デフォルトの名無しさん
NGNG警告: 代入により、キャストなしで整数からポインタを作りました
警告: 代入により、キャストなしで整数からポインタを作りました
警告: ポインタと整数との比較を行なっています
警告: ポインタと整数との比較を行なっています
警告: ポインタと整数との比較を行なっています
”警告”とは?
柔道のルールに反する様な危険な行為を故意に行った、
故意に場外に逃げる行為を行ったなどと審判が判断すると、
その程度により、注意、警告を宣告されます。あまりにひどい行為の場合は、
即「反則負け」となります。
*「警告」は「技あり」を1つ取られたのと同じ扱いになります。
0244デフォルトの名無しさん
NGNG0245デフォルトの名無しさん
NGNGもしくは無いとできない事ってなんですか?
0246デフォルトの名無しさん
NGNG振込先が分からないので使えるお金がない。。。
0247デフォルトの名無しさん
NGNGint a; /*口座を作る*/
a=10; /*口座に振り込む*/
じゃダメなん?
これだと口座10に移動した、とかって事になるのか。
0248デフォルトの名無しさん
NGNGマジレスするなら、aに振り込んでくれという人と、bに振り込んでくれという
人がいるとき、振る込む人にどこに振り込むかおしえるのにポインタが使える。
0249デフォルトの名無しさん
NGNG正直、「そんな事をするな!」と言いたい。
0250237
NGNG家に帰ってコンパイルしてみたら、>>239の方法でコンパイルできた。
何でこうなるの?
http://homepage1.nifty.com/~umetani/ims/2002/20020319001/0.html
↑のエンディアンというものに関係があるのでしょうか?
0251デフォルトの名無しさん
NGNG>>249
0252デフォルトの名無しさん
NGNGそーでつ。
0253デフォルトの名無しさん
NGNGどうやって覚えたの?
0254デフォルトの名無しさん
NGNG0255デフォルトの名無しさん
NGNG英語でポン。
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)へのポインターです。
こんな感じで解釈するみたいです。
0256デフォルトの名無しさん
NGNGC言語ポインター完全制覇の間違いね
0257デフォルトの名無しさん
NGNGvoid (*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);
ここまで整理されるとやっと意味がわかる。
0258デフォルトの名無しさん
NGNGvoid *(*hoge[])(int)(char *);
0259デフォルトの名無しさん
NGNGvoid (*(*hoge[])(int))(char *);
0260デフォルトの名無しさん
NGNG0261デフォルトの名無しさん
NGNGその本最悪だな。俺なら
int* p; // p はintへのポインタです。
int* pArray[10]; // pArray はintへのポインタの(10個の要素を持つ)配列です。
微妙に外れるが配列の書法と関数ポインタの書法は失敗だったと
Cを作ったカーニハン博士自身も仰っている。
0262デフォルトの名無しさん
NGNG俺なら以下が何がいいたいのかわからない。
>>255の本のは
* と [] と () と型名とを「結合順に」「英語で」 読んでいけば理解できるってことだろ?
0263デフォルトの名無しさん
NGNGhoge is an array of a pointer to a function (int) returning a pointer of a function (char *) returning void
int を受け取って、char へのポインタを受け取って void を返す関数へのポインタ、を返す関数
へのポインタの配列
0264255
NGNGたしかにtypedefははずせないね。
とくにc++でtemplate使った構文を作るときになんかないと不便ですね。
>>262
そうそう大事な事書き忘れてた。
>>263
日本語訳こちらの方がよくない
hogeは返り値無しの関数(引数char*)へのポインターを返す関数(int)へのポインターの配列
0265デフォルトの名無しさん
NGNG1.結合順位に従って読み下した順番に並べていけばいいこと。
(日本語だと、日本語の言葉の順番は逆なので、頭の中で並べ直さないといけない)
2.語順は結合順なので、何通りにもなることはない。
(日本語だと>>263>>264のように、同じhogeを扱っているのに、いい訳と悪い訳ができることがある)
3.[]を見たらarray of〜、*を見たらpointer to〜、()を見たらfunction(〜)と言った具合に、機械的・反射的に探すことができる。
0266デフォルトの名無しさん
NGNG先生!日本語で読めました!
0267デフォルトの名無しさん
NGNGだれも日本語で読めないなどは言ってないのですが。
0268デフォルトの名無しさん
NGNG0269デフォルトの名無しさん
NGNG英語だろうが日本語だろうがどっちでもいいよ。
ポインタが理解できないのは単に頭が悪いから。言語は関係ない。
0270デフォルトの名無しさん
NGNGというより語順をあわせたら
解かりやすくなるという物でもなさそう。。。
0271デフォルトの名無しさん
NGNG0272初心者
NGNG猫でもできる・・・であったプログラムなんですが
どうやらエスケープシークエンスがだめなんです。
どうしたらよろしいのでしょうか?
XP使っています。
0273初心者
NGNGよくファイルオープンのあと
if ( fp == NULL )とか
if ( !fp )とか書いてあるんですが
0274デフォルトの名無しさん
NGNG0275デフォルトの名無しさん
NGNG>NULLって結局なんなんですか?
ヌルポインタ
0276デフォルトの名無しさん
NGNGint *a=NULL;
*a = 10;
みたいなことをやると起きるの?
0277デフォルトの名無しさん
NGNG初期化されてないポインタの中には適当な値が入ってます。
だからポインタが何処も指していない状態を厳密に示す
ために値としてNULLを入れてやります。
例の「 if ( !fp ) 」が通用するのは、NULLは実際には
' 0 ' で定義されてたりする事が多いからみたいです。
あまり良くないのかも?それとも無問題?
・ポインタとかポインタへのポインタとか、とにかく戻り値がどこかのアド
レスな関数では、処理が失敗したときNULLを返すように作る事も多いです。
・特にどこも指し示していないポインタはヌルポインタとして初期化します。
こんな感じで良いでしょうか?>>ALL
0278デフォルトの名無しさん
NGNG無問題
例えヌルポがオール0ビットで表されていなくても
「(void *)0」がヌルポになることが保証されている
さらに「if( NULL )」が偽と判断されることも保証されている
気をつける点は「#define NULL (void *)0」を使う事と
ポインタを渡すべきところに0を渡したりしないという事
後は放っておいても大丈夫
0279デフォルトの名無しさん
NGNG感謝!
0280デフォルトの名無しさん
NGNGあと、どこにも向けてないポインタを使うと、
実行時エラーが出るけど、ゴミアドレスが、たまたまOSから見て、不正なアクセス領域を指してなければ、
エラーは出ないもんなの?
つまりゴミアドレスの内容によって、エラーが出たり出なかったりするのかな?
0281デフォルトの名無しさん
NGNG>NULLの定義が入っているのってstdlib.hでいいんだっけ?
sidio.hやstring.hにも定義されている
>どこにも向けてないポインタを使うと、
どこにも向けてないポインタ=NULL
では?
0282デフォルトの名無しさん
NGNG0283デフォルトの名無しさん
NGNGと ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←>>282
0284デフォルトの名無しさん
NGNG初期化していない、って意味かと。
だとしたら、
>>280
>たまたまOSから見て、不正なアクセス領域を指してなければ
問題なくアクセス出来るでしょう。読み取りデータには意味が無いですが。
ただし、読み取りは可能でも書き込みは出来ない領域なんてのがある
場合があって、そのときは他のエラーが発生するでしょうね。
0285デフォルトの名無しさん
NGNG「NULLで初期化する」という言い方もあるから
「初期化していない」ではないと思う。
0286デフォルトの名無しさん
NGNG馬鹿発見
0287デフォルトの名無しさん
NGNG馬鹿は認めるので、説明してください。
0288デフォルトの名無しさん
NGNG0289デフォルトの名無しさん
NGNG* 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);
}
0290デフォルトの名無しさん
NGNG* とりあえずこんな感じで、希望の動作になりました。
* 惚け防止に最適 > 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);
}
0291デフォルトの名無しさん
NGNG>「NULLで初期化する」という言い方もある
のがわかっているなら、「初期化していない」ということになるだろう?
C言語というより日本語の理解の問題のような気もするが念のため
「初期化していない」
int *ptr;
「NULLで初期化する」
int *ptr=NULL;
0292284
NGNG「NULL 以外で初期化する」
int *ptr = (int *)0x1000;
「初期化したけどどこにも向いていないポインタは存在する」
みたいな事を >>285 は言いたいんじゃないかと。
// でもそこで争う気はないんでスルーした次第。
0293デフォルトの名無しさん
NGNGダングリングポインタの違いもわからないのですか?
0294デフォルトの名無しさん
NGNG0295デフォルトの名無しさん
NGNG0296284
NGNG正式な定義がどうかは知らないけど (あるの?)、世間的には
1. 解放済みの領域を指すポインタ
2. (1. に加えて) 関数が戻した、そのローカル変数へのポインタ
3. とにかく何処を指しているか解らないポインタすべて
の 3種類あるよね。
俺の認識では 2. なんだけど。
0297デフォルトの名無しさん
NGNGhttp://dictionary.reference.com/search?q=dangling%20pointer
簡単に説明すると、かつては正しい場所をさしていたものが、
freeやreallocなどにより、有効なものではなくなり、宙ぶらりんの
状態になったものを言う。
なので、2,3は普通ダングリングポインタとは言わない。
0298デフォルトの名無しさん
NGNGchar *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
}
0299デフォルトの名無しさん
NGNG>p = realloc(2048);
どこを再確保する気?
0300284
NGNG実のところ 1. と 2. は区別する必要はないと
自分では思ってるんだけど。
そういや C++ だと、こういうのもあるね。
const char *ptr = std::string("ABC").c_str();
sprintf("%s\n", ptr); // pointed to temporary instance
>>297
で、そこは“普通”あるいは“正式な定義”なの?
# そもそも「正式」って誰が決めるんだろうね。
0301デフォルトの名無しさん
NGNG参照先の英文にはfreeともreallocとも書いていないのに、
freeやreallocに限定して、>296の2.を否定するのは作為的だな。
0302デフォルトの名無しさん
NGNG[Jargon File]とあったのでnew hacker's dictionaryを見てみたらあったから、そのまま乗せるぞ
dangling pointer [原義:宙ぶらりんのポインタ]
n. 実際にはどこにもたどり着かない参照(Cなど一部の言語では、実際には何にも有効
なものを指していないポインタ)。指していた相手が移動したり消えたりしたために起
こるのが普通。この語は技術的は意味を広げてハッカー語として使われており、たと
えば、もう国の反対側に引っ越してしまった人の市内電話番号は宙ぶらりんポインタ
だ。dead linkと比較せよ。
0303デフォルトの名無しさん
NGNG296の2は、単なるinvalid pointer
0304デフォルトの名無しさん
NGNG別に「正式」なんぞを決める必要は無く、みんながどう使ってるかが問題なのでは?
ググればわかるだろ。
0305デフォルトの名無しさん
NGNGいくらでも文字は入るけど、ヒープ領域をぶっ壊してるだけ
ポインタを宣言した時点では、どこも指していない。デタラメなアドレスが入っているだけで、有効なアドレスは指していない。
freeで解放した時点では、free解放直前までと同じアドレスが入っている。しかし、解放してしまえば、有効なアドレスを指しているとは言えない。
「ポインタを宣言したら、NULLを入れておく」、
「freeで解放したらNULLにしておく」、
といったように、これらのどこも指してないポインタを、プログラマが明示し、
このポインタを使用する関数に、ポインタがNULLのときは、エラーを返すようにする、
というのはよく使われる手段である。
0306デフォルトの名無しさん
NGNGたまたま有効なアドレスをさしているということはありえる。
0307デフォルトの名無しさん
NGNGあ、それね。
XPのcmd.exeは標準でANSI.SYSを読み込まないから、無理だよ。
漏れもconfig.NTにDEVICE文を付け加えてみたけど、どうも上手くいかない。
まあ、SetConsoleTextAttribute()を使いなさいってこった。
0308デフォルトの名無しさん
NGNGエラーの発生ポイントをチェックできるし。
0309デフォルトの名無しさん
NGNGたまたま有効なアドレスをさしているということがありえるから、バグを見つけにくくなるわけで、
なら、最初っからNULLにしておけば必ずエラーになるからバグが見つけやすくなるというのが
>>305の言いたいことでないの?
0310デフォルトの名無しさん
NGNG何が言いたいのかは知らんが、間違ったことを言ってるから指摘しただけだ。
0311デフォルトの名無しさん
NGNG間違ったことって…
そんな重箱の隅をつついて初心者に対して難解な文章にする必要は無いだろう
0312デフォルトの名無しさん
NGNG君、技術者に向いてないよ。止めたら?
0313デフォルトの名無しさん
NGNGどっちにも頷いてしまう・・・
0314デフォルトの名無しさん
NGNG>何が言いたいのかは知らんが、間違ったことを言ってるから指摘しただけだ。
相手の言いたいことすら理解できていないのに、
発言する奴の方が技術者に向いていないと思うが?
因みに >>309 の言いたかったことを代弁すると・・・
「お前の指摘(?)は的外れ。出直して来い」
0315デフォルトの名無しさん
NGNGif(!pt)
0316310
NGNG>>312は俺じゃないんだが、それはおいとく。
314は312に向けた発言だと思うが、312がどれほど技術者に向いてなかろうが、
君の資質とは全く関係の無いことだ。もう少し冷静になって書き込めよ。
それに他人の代弁なんかする必要は無い。話がややこしくなるだけで、何の利益も無い。
0317310
NGNGCプログラマであれば常識の範囲でしかないことだろう?
0318デフォルトの名無しさん
NGNG>それに他人の代弁なんかする必要は無い。話がややこしくなるだけで、何の利益も無い。
君、技術者に向いてないよ。止めたら?
0320デフォルトの名無しさん
NGNG0321デフォルトの名無しさん
NGNGで、常識を知らん奴に教えるときには、その内容にうそが含まれていてもよいとでも?
0322デフォルトの名無しさん
NGNG0323デフォルトの名無しさん
NGNG関数・・・void func(int a[]) の引数にint型の配列s[]の先頭要素のアドレス・・・s(&s[0]) を渡せる理由が分かりません。
もちろんポインタ変数にアドレスを渡す方法なら余裕で理解できますが。こういうやつvoid func(int * a)
0324デフォルトの名無しさん
NGNGここ読めワンワン
http://www.catnet.ne.jp/kouno/c_faq/c6.html
0325デフォルトの名無しさん
NGNG0326デフォルトの名無しさん
NGNG0327デフォルトの名無しさん
NGNGなんでそんなに逃げ腰なんだ
0328アンチポインター
NGNGアドレスをポインタと呼ぶな。
そもそもポ゚インターの概念を廃止するべきだ。
0329デフォルトの名無しさん
NGNG0330デフォルトの名無しさん
NGNG??
0331デフォルトの名無しさん
NGNG同意。混乱の素だよな。ポインタって禁止用語にすればいい。
0332デフォルトの名無しさん
NGNGトラウマ糞コード書く香具師がいるから。
0333デフォルトの名無しさん
NGNG0334デフォルトの名無しさん
NGNG0335デフォルトの名無しさん
NGNG0336デフォルトの名無しさん
NGNG0337デフォルトの名無しさん
NGNGhttp://member.nifty.ne.jp/maebashi/programmer/pointer.html
「ポインタが難しいのではない。
C言語の、配列とポインタにかかわる文法が混乱しているだけだ。」
----
ガイシュツ?
0338デフォルトの名無しさん
NGNG>>255でおいらがしーぼん紹介してあげたんだな〜。
よって既出!!まあ。サイトまでは紹介してあげてなかったけどね。
0339デフォルトの名無しさん
NGNG* 笑い話に出てくる、ポインタのポインタのポインタの...
* というのを実験してみた。
*/
#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);
}
0340デフォルトの名無しさん
NGNG何の実験だか知らないが、
> *p = test; *q = p; *r = q; *s = r;
ぬるぽ。
0341デフォルトの名無しさん
NGNG0342デフォルトの名無しさん
NGNG#define malloc(n) calloc(1,n)
をコメントアウトすると動かなくなるんだ
0343デフォルトの名無しさん
NGNG0344デフォルトの名無しさん
NGNG16ビットモードだと dx による間接アドレッシングはできない。
bx, si, di のどれかにしろ。
0345デフォルトの名無しさん
NGNG( ゚Д゚ ,,) { ギコ猫だってCやるんだぜ。 )
_ | ̄ ̄||_)_
/ /|――||/旦/|
| ̄| ̄ ̄ ̄ ̄ ̄| . |
|三|_____|/ カタカタ・・・・
0346デフォルトの名無しさん
NGNG>アドレスをポインタと呼ぶな。
呼んでない。
恐らく、そう呼んでいるのは理解してないヤシだけ。
0347デフォルトの名無しさん
NGNGってやったらaもbもポインタになるようにしてほしい。
0348デフォルトの名無しさん
NGNG0349デフォルトの名無しさん
NGNG0350デフォルトの名無しさん
NGNGint i,j,k;
int *p,*q,*r;
こんなことしてるのは少数派だろうが。。。
0351デフォルトの名無しさん
NGNGtypedef int* inpee
inpee a,b;
0352デフォルトの名無しさん
NGNG0353デフォルトの名無しさん
NGNGそういう人はCのみで終る人生でありC++にステップアップできない人だからほっときましょう。
0354デフォルトの名無しさん
NGNGあー、俺もそれは嫌だな。
いちいち定義する必要があるのかと一晩中(ry
お前 * 見たくないだけちゃうんか、と。
0355デフォルトの名無しさん
NGNG0356デフォルトの名無しさん
NGNGお注射しますか?それともフェラチ●しますか?
0357デフォルトの名無しさん
NGNGgoto *(void (*)())0x6000;
と書いたときの動作と意味がわかりません。
0358デフォルトの名無しさん
NGNG0359デフォルトの名無しさん
NGNG0x6000の指すアドレスにジャンプせよ。
0x6000にはジャンプしないと思う
0360デフォルトの名無しさん
NGNGポインタは、アドレスを格納した変数のことだよ。
メモリに直接アクセスできるから、配列を使うより効率的なんだ。
0361デフォルトの名無しさん
NGNG> メモリに直接アクセスできるから、配列を使うより効率的なんだ。
こう信じ込んでいる奴って多いのか ?
0362デフォルトの名無しさん
NGNG0x6000にジャンプさせるには
goto (void (*)())0x6000;
じゃない?
手元にクロス環境がないのでわからないけど。
0363デフォルトの名無しさん
NGNGそれはそれで正しいんじゃない?
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);
}
}
}
}
}
0364デフォルトの名無しさん
NGNG悪いけど、これを配列で表現してみてくれ。
(n+=*(dp+n); の型が不一致であることと、関数の戻り値が指定されていないことにはあえて触れないが。)
0365デフォルトの名無しさん
NGNG0366デフォルトの名無しさん
NGNG分かってない
0367名無し@沢村
NGNG>メモリに直接アクセスできるから、配列を使うより効率的なんだ。
ほう…配列は間接的にメモリにアクセスするのかい?
0368デフォルトの名無しさん
NGNGint型のポインタ、配列がそれぞれあるとして、
ポインタの場合
mov eax, dword ptr[edx] ; ポインタ参照
lea edx dword ptr[edx+4] ;ポインタ自身をインクリメント
配列の場合
mov eax, dword ptr[edx+ecx*4] ; 配列参照
inc ecx ;配列インデックスをインクリメント
見ての通り、ポインタにすると使用レジスタを減らせる
0369デフォルトの名無しさん
NGNG添え字変数の参照コストは比較しながら
ポインタ変数自体への参照コストは無視していいってのかね。
配列がスタック上なら
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
0370デフォルトの名無しさん
NGNG毎回するので遅くなる程度だ。
まともなコンパイラにちゃんと最適化させたら、たいてい差がなくなる。
0371デフォルトの名無しさん
NGNG0372名無し@沢村
NGNGmov eax, dword ptr[edx] ; の場合、66 67 8B 02となってModR/Mバイトしか使わないが、
mov eax, dword [edx+ecx*4] ;の場合、66 67 8B 04 8Aとなるから、SIBバイトも使うってことか?
0374デフォルトの名無しさん
NGNG自作関数にはポインタは絶対に必要!
0375デフォルトの名無しさん
NGNG>1 は1に書いてある内容を参照せよって意味だしな。
0376デフォルトの名無しさん
NGNG0377デフォルトの名無しさん
NGNGもっとわかりやすくお願いします。
要はポインタ渡しとアドレス渡しは一緒?
ポインタってのはそこの場所に この変数Aが常駐してますよ って事?
※だからそこの値を参照したり 値を変更したり出来る
アドレス渡しも一緒?
0378デフォルトの名無しさん
NGNG0379デフォルトの名無しさん
NGNGじゃあなぜ文言をわざわざ分けているのですか?
0380デフォルトの名無しさん
NGNG0381デフォルトの名無しさん
NGNG女の子は実体
0382デフォルトの名無しさん
NGNGそれって実態が(このレスでいう女の子?)
アドレス渡しってこってすかい?
そこを参照すればいつでも女の子がいますよ みたいな
0383デフォルトの名無しさん
NGNGスタティック変数のアドレス → 愛人
ローカル変数のアドレス → 現地妻
アロケートした領域のアドレス → 売女
0384デフォルトの名無しさん
NGNGここでいうアドレスはあくまでも電話番号
0385デフォルトの名無しさん
NGNG0386デフォルトの名無しさん
NGNGアロケートしたらフリーしなさい
メンバ変数には電車で毎朝会う子か?
0387デフォルトの名無しさん
NGNG0388デフォルトの名無しさん
NGNG0389デフォルトの名無しさん
NGNG一通りのエラーチェックのすんだ後
必要って時のギリギリのときにnewするのがよろし
0390デフォルトの名無しさん
NGNG0391デフォルトの名無しさん
NGNG0392デフォルトの名無しさん
NGNG0393デフォルトの名無しさん
NGNG0394デフォルトの名無しさん
NGNG0395デフォルトの名無しさん
NGNG間接アドレッシングがまともに装備されてないCPUがあることを初めて知った。
びっくらこいた。
0396デフォルトの名無しさん
NGNGアドレスをかくのうしているはいれつのメモリのことですっ!!!!!11
0397デフォルトの名無しさん
NGNG_| ̄|○
0398デフォルトの名無しさん
NGNG0399ダン
NGNG0400デフォルトの名無しさん
NGNGそれがアドレスで実装されてるとは限らない。なんかのindexかもしれない。
メモリとも限らないかもしれない。
0401デフォルトの名無しさん
NGNG0402Alto
NGNG0403デフォルトの名無しさん
NGNGはぁ?お前全く計算機のハードウェアがわかってないな。
オブジェクトはメモリ上にマッピングされなけりゃどこに
実装されるか考えてみろ。アホが
しかもindexとは何を意味してるんだ?それが物理的にどこに格納
されるか考えてみろ。
最後にスレタイよく読め。C++とは一言も書いてないだろうがバカ
0404デフォルトの名無しさん
NGNGC++で拡大解釈されたレジスタ変数へのポインタをありがたがってる
文法バカ -> ハードウェアのかけらも知らない糞
0405デフォルトの名無しさん
NGNG本のしおり
0406デフォルトの名無しさん
NGNG0407デフォルトの名無しさん
NGNGお前はレジスタウィンドウや Mapped I/O すら知らないらしいな。
0408デフォルトの名無しさん
NGNG0409デフォルトの名無しさん
NGNGいや、>>403-404 は「オブジェクト」と聞くと「C++ かよ!」と思ってしまう
OOP 挫折組だろう。
0410デフォルトの名無しさん
NGNG0411デフォルトの名無しさん
NGNGチッ!あのなぁ。レジスタウィンドウなどというのはレジスタをメモリ
代わりに使おうって発想なんだからメモリといっても差し支えないだろうが!
しかもMapped I/Dの前には Memoryの修飾詞がつくだろうが、少なくとも
コンパイラ側から見ればメモリと思ってアクセスしてる。だから
Memory Mapped I/Oなんだよ。
>>409
pure Cではレジスタへのポインタは許されてなかったという経緯も知らんのか?
アフォが!
0412デフォルトの名無しさん
NGNG0413デフォルトの名無しさん
NGNGint 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;
}
という風にポインタのインクリメント/デクリメントに持ち込むほうが一般的に
速い。
0414デフォルトの名無しさん
NGNG最近のPCでもそうなの?
0415デフォルトの名無しさん
NGNG0416デフォルトの名無しさん
NGNGで、C++ は何の関係があるんですか?
0417デフォルトの名無しさん
NGNG>しかもindexとは何を意味してるんだ?
例えば、非バイトマシンにおけるバイト位置とかじゃない?
0418デフォルトの名無しさん
NGNG最近では>>413の上のが速い
0419デフォルトの名無しさん
NGNGそれは間違い。学生はスッコンデロ!コンパイルしてコード見ろ。
さらにカウントは0を終了条件にするほうが速いがこちらはどんな
オプティマイザでも一応対応してる。
0420デフォルトの名無しさん
NGNGポインタのインクリメントやデクリメントはCPUにハードウェアとして実装されてる機能であって、
これを下手にアドレッシング計算されると速度低下につながる。
まぁ、日英/英日翻訳がまともに機能するようになればコンパイラに頼り切ってもいいだろうけどね。
今の自動翻訳で意味わかるか?
0421デフォルトの名無しさん
NGNG0422デフォルトの名無しさん
NGNGレジスタって何CPUって何変数って何インクリメントって何デクリメントって何
ハードウェアって何実装って何アドレッシング計算って何コンパイラって何?
0423デフォルトの名無しさん
NGNG>ポインタのインクリメントやデクリメントはCPUにハードウェアとして実装されてる機能であって
絶対だな?
0424デフォルトの名無しさん
NGNGメモリもなくてデータ/プログラムともレジスタだけで動く。
0425デフォルトの名無しさん
NGNGお前は実際にコーディングして確かめたのか?
頼むから知識だけで物事を語るのはやめてくれよな。
ちなみに漏れの環境での結果は、(1000万回ループ)
>>413の上: 7937(ms)
>>413の下: 8078(ms)
まぁ大差はないがそういうこった。
漏れの環境がおかしいとか言われそうだなw
まぁ別にいいけど( ´ー`)y━〜~~
0426デフォルトの名無しさん
NGNG俺ゴリズムを駆使した挙句、猛烈に遅いコード書いたりするよね。
0427デフォルトの名無しさん
NGNGあ、プログラマじゃないよね。じゃ仕方ないか。
0428デフォルトの名無しさん
NGNG正しくは、
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;
}
}
0429426
NGNG0430デフォルトの名無しさん
NGNGfuncA は
.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
0431デフォルトの名無しさん
NGNG.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が少ないな。
0432デフォルトの名無しさん
NGNGお前いったいコンパイラに何使った?
次のプログラムで確認してみろ!
#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();
}
0433デフォルトの名無しさん
NGNGindex % 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より倍遅い。これでも上が速いというか?
0434デフォルトの名無しさん
NGNG0435デフォルトの名無しさん
NGNG…恥の上塗りだな。
そんなもの、コンパイラにもプロセッサにも依存する。
0436デフォルトの名無しさん
NGNG間抜けですね。
0437デフォルトの名無しさん
NGNGコンパイラの話をしてるのにコンパイラにもプロセサにも依存するのは当然だろうが。
86系でクロック数をカウントできるデバッガでも持ってりゃそれで示してやるがあいにく
持ち合わせてないんでな。
それともタイマ等もすべて止められるOSでポート叩いてロジアナでモニタすれば計測できるが
お前はそれやったのかい?
0439デフォルトの名無しさん
NGNG0440デフォルトの名無しさん
NGNG0441デフォルトの名無しさん
NGNG余計な命令が含まれてしまったりするのではないだろうか。
0442デフォルトの名無しさん
NGNG0443デフォルトの名無しさん
NGNGグローバル変数は世界遺産
ローカル変数は時価の高い土地
アロケート領域は借地
0444デフォルトの名無しさん
NGNG理論的に計算して時間を求めたほうがいいよ。
たとえば1MIPSのコンピュータでどうとか。
速度はある程度遅い方が顕著になるともう
0445田中康夫
NGNGって言われてイラクくんだりまで尻尾ふってついてく小泉ワンワンのことさー。
0446デフォルトの名無しさん
NGNG本っ当に頭悪いね…
>>432 のコードは、前者が速いこともあれば後者が速いこともある。
ふつーは後者が速い、なんてのは幻想。
0447デフォルトの名無しさん
NGNGお前アセンブリコードをまともに書いたことのない最低のド素人だな。
C書く前にCPUの構造を一から勉強しなおせ。
0448デフォルトの名無しさん
NGNG0449デフォルトの名無しさん
NGNG0450デフォルトの名無しさん
NGNG0451デフォルトの名無しさん
NGNGアセンブリは死ぬほど書きました。
モノが ROM なのでハンドアセンブルも多かったですが。
趣味では CPU も TTL ランダムロジックで幾つか作りましたよ。
尤もそのマシンはパイプラインや先読みキャッシュ、分岐予測なんてのは
備えてませんので、あなたの思うような結果 (後者が速い) に
なるでしょうね。
0452デフォルトの名無しさん
NGNG>ふつーは後者が速い、なんてのは幻想。
それはお前のおつむが幻想見てるからだよ。配列のアドレッシングに出来るだけポインタの
インクリメント/デクリメントでアクセスできるようにデータをあらかじめ並べ替えて配置
するなどというのは常套手段。ループカウンタでお手軽にアクセスするのは
人間にはわかりやすくても機械にとっては負担が大きい。
0453デフォルトの名無しさん
NGNGコンパイラによっても処理系によっても結果は違う、が厳密には正解だと思う。
だが、現実的にはこの程度のコードで差を生じさせるようなアホなコンパイラも
貧弱な処理系も稀な気がする。(組み込み系とかを除けば)
0454453
NGNG(私に言わせると素っ頓狂なこと)言ってる人は、頭の中に昔の8ビットの
CPUとか想定してないか?
0455デフォルトの名無しさん
NGNG手元にLinuxかFreeBSDのソースコードあったら見てみな。カーネルだけでなく
ライブラリでもアセンブラで書かれてるものが結構あるから。Cのコード見てアセンブリ
結果を予測できないようじゃままごとアプリ書くのが関の山
0456デフォルトの名無しさん
NGNG数万行のCのコードを脳内アセンブルできないとダメですか。
0457デフォルトの名無しさん
NGNG>>455にとってはその程度朝飯前
0458デフォルトの名無しさん
NGNG0459デフォルトの名無しさん
NGNG0460デフォルトの名無しさん
NGNG0461デフォルトの名無しさん
NGNGVC++ 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) 最初に呼び出された関数が遅い」でした。
046256
NGNGそれを同じコードはいちゃオプティマイズしすぎだと思うが?
0463デフォルトの名無しさん
NGNGfor (int i=0; i<2; i++)
std::cout << "#" << i + 1 << ": " << s[i] << " [msec]" << std::endl;
ね。
0464460
NGNG# 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
ループ部分は同じでしょ?
0465デフォルトの名無しさん
NGNGカウンタは、はじめに1023がセットされて
addcc %g3, -1, %g3
でデクリメント。
ポインタも
sethi %hi(x+4092), %g2
で配列の末尾がレジスタg2に設定されて、
add %g2, -4, %g2
で4byteずつデクリメント。
ループ途中でiを引数にした関数でもコールすると違ってくるんだろな
0466デフォルトの名無しさん
NGNG末尾設定してることだけが違う。
0467デフォルトの名無しさん
NGNG0468デフォルトの名無しさん
NGNG0469デフォルトの名無しさん
NGNG>413のポインタの使い方おかしくね?
どうおかしいの?
0470デフォルトの名無しさん
NGNGforのループでiのかわりにpxのポインタを使っていないとこ。
あーでもインクリメントしたiを入れたいのか。例が悪いな。
0471デフォルトの名無しさん
NGNG0472デフォルトの名無しさん
NGNG生半可な知識を振り回すと恥をかくことが多い。
0473デフォルトの名無しさん
NGNG0474デフォルトの名無しさん
NGNG0475デフォルトの名無しさん
NGNG>>461 >>464
0476デフォルトの名無しさん
NGNG0477デフォルトの名無しさん
NGNG16bitCPU時代は、アドレスも16bitで表現していた。最大アドレス値は高々64Kbyte。
しかしメモリがメガ単位まで増えると、64Kbyteを超えるアドレスにアクセスする必要
が出てきてしまった。
そこで、アドレスを上位と下位の二つに分割して、64Kbyte以内のメモリ単位(この範
囲をセグメントという)のプログラミングでは通常の16bitポインタを使い、セグメントを
越えるメモリ操作は、上記の上位アドレスを併用することで実現した。
このような拡張アドレスを操作するポインタを farポインタとよび、これに対して従来
の物をnearポインタと呼ぶ。
またfarポインタの上位アドレスは、セグメントの基点をあらわすことからセグメントア
ドレス、下位アドレスはセグメントを基点としたオフセット表現なので、オフセットアド
レスと呼ぶこともある。
現在ではCPUが32bitになり、アドレスバスも32bitに増えた。このため表現できるア
ドレス空間も4Gまで増えたため、farポインタを使う必要性はほとんどなくなっている。
0478デフォルトの名無しさん
NGNG0479デフォルトの名無しさん
NGNG0480デフォルトの名無しさん
NGNG0481デフォルトの名無しさん
NGNG0482デフォルトの名無しさん
NGNG文脈によってはまったく同じ
0483デフォルトの名無しさん
NGNGツリー構造の実装が困難
スタックの実装が困難
キューの実装が困難
…
0484デフォルトの名無しさん
NGNG全て参照を使うことでもっと簡単に安全に実装できますね。
0485デフォルトの名無しさん
NGNG0486デフォルトの名無しさん
NGNGあ!
0487おでん
NGNGLccWinだと、こうなりました。
(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
やっぱり、先に呼ばれたほうが遅いですね?
0488デフォルトの名無しさん
NGNG0489デフォルトの名無しさん
NGNG>>483の例はすべてクラスのメンバに他(or 自分)のクラスのポインタを含む場合だが。参照でどうやって書くの?
0490デフォルトの名無しさん
NGNGgccのbits/list.tccではポインタ使って書いてる。
0491デフォルトの名無しさん
NGNGポポインタ
0492デフォルトの名無しさん
NGNG0493デフォルトの名無しさん
NGNG0494名無し@沢村
NGNG本に書いてあるよ、本読めよ。
幼稚園かおまえ?
0495デフォルトの名無しさん
NGNG0496デフォルトの名無しさん
NGNGそれはハードを操作するからじゃないのかね。
ブートローダとか、HDDの操作とか。
スピードのためにアセンブリ使っているわけでないような気がするが。
0497デフォルトの名無しさん
NGNG計測結果が激しく違う予感がするぞぉ。
プロセスの管理方法とかが一緒なの毛?
やるならブートローダーにそのプログラムを直に書いて、FDDでブートさせて計測したほうがよさそうな予感。
ってかそこまでやっても何も得られん・・・ゲハ
0498デフォルトの名無しさん
NGNG0499デフォルトの名無しさん
NGNG0500デフォルトの名無しさん
NGNGあとは参照にすべしで決まりだ。
0501デフォルトの名無しさん
NGNGstrcpy() とかのソース見れ。
いくつかのプロセサは、文字列操作に特化した命令を持ってるから、そういうのを使うためにアセンブラで書くのは珍しくない。
0502デフォルトの名無しさん
NGNG参照なんてなもんはなくても構わない。
0503デフォルトの名無しさん
NGNG0504デフォルトの名無しさん
NGNG0505佐々木洋子
NGNG0506デフォルトの名無しさん
NGNG上級者に、初心者はポインタの意味だけでつまずいてるわけじゃないことを
理解させることは容易じゃないようだ
0507デフォルトの名無しさん
NGNGアドレスがあります。
たとえば、下の図がわかりやすいと思います。
左側にあるのがアドレスで囲ってあるところが中に入っているビット列が
意味する数字です。
+---+
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という数字を示すことになります。
0509デフォルトの名無しさん
NGNG0510デフォルトの名無しさん
NGNGどこのアドレス指してるとかの説明よりも
ディレクトリでかも知れんなぁ
0511デフォルトの名無しさん
NGNG0512デフォルトの名無しさん
NGNG0513デフォルトの名無しさん
NGNG0514デフォルトの名無しさん
NGNGへったくそな説明やなぁ〜
0515デフォルトの名無しさん
NGNG上手な説明をどうぞ。逃げないでちゃんと解説よろ。
0516デフォルトの名無しさん
NGNG「ポインタ」の箇所を「アドレス変数」って読み替えるといいよ、って言ってる。
0517デフォルトの名無しさん
NGNG「int型のアドレスを指す変数」
で
大体理解できるんじゃないか?
0518デフォルトの名無しさん
NGNGtxtなら1行づつ読み取れるのですがexcelの場合は、そうもいかないみたいでして
excelの場合の読み取りの仕方を教えてください。
以下に僕が作ったサンプルプログラムを書きます。
br = new BufferedReader (
new InputStreamReader (
new FileInputStream( "SJISin1.txt" ), "SJIS" ) );
while( ( str = br.readLine() ) != null ) {
System.out.println( str );
}
というような感じです。宜しくお願いします。
なお部分的に抽出する場合も教えていただけるとうれしいです。
例えば3行2列目の文字列を読み取るなどです。
0519デフォルトの名無しさん
NGNG0520デフォルトの名無しさん
NGNG0521デフォルトの名無しさん
NGNGまったりと教えてやれよ。
0522デフォルトの名無しさん
NGNG0523デフォルトの名無しさん
NGNG0524522,523
NGNG0525デフォルトの名無しさん
NGNG0526デフォルトの名無しさん
05/02/15 04:18:170527デフォルトの名無しさん
05/02/15 15:04:210528527
05/02/15 15:04:480529デフォルトの名無しさん
05/02/28 17:47:180530デフォルトの名無しさん
2005/04/27(水) 16:28:58{
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を指す
という解釈で合ってますでしょうか。
0531デフォルトの名無しさん
2005/04/28(木) 13:33:39あってるよ
0532デフォルトの名無しさん
2005/04/28(木) 14:50:37「ポインタ値=アドレス値」とは限らない。
「ポインタ値=オブジェクトを指し示す値」だ。
環境によってはアドレス値であるかもしれないし、
オフセットアドレスであるかもしれない。
0533デフォルトの名無しさん
2005/04/29(金) 08:29:580534デフォルトの名無しさん
2005/04/29(金) 11:38:590535デフォルトの名無しさん
2005/04/29(金) 14:37:27もうポインタの本を何冊買ったか覚えてねえ
タンスとかの図を載せてるけど
コンピュータの中にタンスが入るわけねえだろとか
余計なことばっかり気になってしまう
これはもう、能力とかじゃなくて相性だな
0536デフォルトの名無しさん
2005/04/29(金) 15:26:38変数とか配列とかを箱が並んでる絵で説明してて、わけわからんかったな
それはともかく、Cのポインタは便利すぎるのか、素人が苦し紛れに
使って、わかりづらいコードになること多い。配列使え
0537デフォルトの名無しさん
2005/04/29(金) 16:29:14能力だと思う。
0538デフォルトの名無しさん
2005/04/29(金) 18:20:24コーディング方法ってあるんだろ?
実行ファイルのパフォーマンスは最高なんだから
あとはポインタさえなけりゃ最強の言語なんだよ
なっ教えてくれよ
0539デフォルトの名無しさん
2005/04/29(金) 18:52:56クロヌ
「ポインタの本」なんつーターゲット絞り込みすぎ気味の本なんてあるのか?
0540デフォルトの名無しさん
2005/04/29(金) 18:54:020541デフォルトの名無しさん
2005/04/29(金) 18:54:16ポインタ使わなきゃ関数にヒキ渡せないものばっかりジャン
0542デフォルトの名無しさん
2005/04/29(金) 19:25:110543デフォルトの名無しさん
2005/04/29(金) 19:49:55いま「ポインタが理解できない理由」読んでるけど、
こんなんを初めてでも簡単に理解できる人は凄いよ。
Cの勉強し始めて「頭良い・悪い」が何なのか分かった気がする。
0544デフォルトの名無しさん
2005/04/29(金) 20:44:17そういう本もある意味変だよな。
わからない理由がわかってたら
それはわかってるということだからな。
0545デフォルトの名無しさん
2005/04/29(金) 20:58:160546デフォルトの名無しさん
2005/04/29(金) 23:18:240547デフォルトの名無しさん
2005/04/30(土) 08:50:54メモリ構造理解するとかしないでしょ
0548デフォルトの名無しさん
2005/04/30(土) 09:45:29DOSのころは、セグメントだのバンクだのっていう瑣末なことまで気にしていたが、
今となっちゃただ単にリニアなアドレスを持つ仮想のメモリ空間を相手にするだけだ。
だから、そこじゃないんだろ難しいのは。
例のポインタに関するCの変てな表記法や文化が混乱の元。
関数ポインタとか、配列とポインタの混同とかさ。
ポインタ変数の、組み込み型変数としての普遍性と特殊性を押さえないとな。
0549デフォルトの名無しさん
2005/04/30(土) 09:56:160550デフォルトの名無しさん
2005/04/30(土) 10:22:400551デフォルトの名無しさん
2005/04/30(土) 10:31:04Win32SDKで使ってたようなきがするんだけど、いまいち実感が無くて。
誰かおしえぇて。
0552デフォルトの名無しさん
2005/04/30(土) 10:44:22関数を変数に入れたいときに使う。
変数に入れられれば、関数の引数として渡せるようにもなる。
0553デフォルトの名無しさん
2005/04/30(土) 10:55:090554デフォルトの名無しさん
2005/04/30(土) 10:57:30REGISTERCLASSEX、CreateWindow、CreateDialog
0555デフォルトの名無しさん
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;
}
0556デフォルトの名無しさん
2005/04/30(土) 11:11:550557デフォルトの名無しさん
2005/04/30(土) 11:24:43(・∀・ )< HSPで大金持ちになるんだ。
_φ___⊂)__ \_______________
/旦/三/ /|
| ̄ ̄ ̄ ̄ ̄| |
| |/
0558デフォルトの名無しさん
2005/04/30(土) 12:50:11しかしそういわれてモナー
size ofみたいにaddress of演算子とかその逆のcontent of演算子とかにする?
長々しくなってヤダー
0559デフォルトの名無しさん
2005/04/30(土) 18:37:120560デフォルトの名無しさん
2005/04/30(土) 20:05:45教えてください。
0561デフォルトの名無しさん
2005/04/30(土) 20:35:45ヒント:文字列定数が格納されているところのポインタ
0562デフォルトの名無しさん
2005/04/30(土) 20:52:350563デフォルトの名無しさん
2005/04/30(土) 21:19:260564デフォルトの名無しさん
2005/04/30(土) 21:44:380565デフォルトの名無しさん
2005/04/30(土) 21:57:440566デフォルトの名無しさん
2005/04/30(土) 21:59:50文字列定数はポインタじゃないよ。
0567デフォルトの名無しさん
2005/04/30(土) 22:04:41うひょ〜
てゆーか
うげ〜
0568デフォルトの名無しさん
2005/04/30(土) 22:07:56typedef PVOID APVOID[];
typedef PVOID FUNC(APVOID *);
typedef FUNC *PFUNC;
typedef PFUNC APFUNC[];
0569デフォルトの名無しさん
2005/04/30(土) 22:12:08*(*)[] ってばかじゃねーの?
0570デフォルトの名無しさん
2005/04/30(土) 22:15:500571デフォルトの名無しさん
2005/04/30(土) 22:20:47・関数ポインタ と その配列。
・配列へのポインタ
・引数と返り値では、仮引数名が省略される。
この3つを押さえれば、どんな複雑な型でも書ける。
0572デフォルトの名無しさん
2005/04/30(土) 22:25:450573デフォルトの名無しさん
2005/04/30(土) 22:27:01char szB[] = "1234568790";
これの違いを適切に言えるなら初心者脱出。
0574デフォルトの名無しさん
2005/04/30(土) 22:30:19導師よ!
0575デフォルトの名無しさん
2005/04/30(土) 22:57:55配列先頭要素へのポインタで事足りる。
0576デフォルトの名無しさん
2005/04/30(土) 23:09:202次元配列へのポインタをしまうときに使う。
int aa[2][2], a[2];
int (*pa)[2];
pa = &a
pa = aa;
0577デフォルトの名無しさん
2005/04/30(土) 23:44:22アドレス参照したいなら&でいいんじゃないの?
0578デフォルトの名無しさん
2005/04/30(土) 23:46:50なくても、プログラミング出来なくはない。
でもめんどくさいよ。
0579デフォルトの名無しさん
2005/05/01(日) 00:05:53> char* szA = "1234568790";
char型のデータを格納するメモリのアドレスを格納するための
変数「szA」を定義し、文字列データ"1234568790"の格納されている
メモリの先頭アドレスを格納する。
> char szB[] = "1234568790";
char型の配列変数「szB」を定義し、文字列データ"1234568790"を
構成する各文字コードデータをszB[0]から順に格納する。
…これで合ってますかね
0580デフォルトの名無しさん
2005/05/01(日) 01:16:19intのポインタとか便利じゃね?
アドレスだと、インクリするときにa=a+sizeof(int); とか面倒じゃね?
ポインタならa++;で済むからテララクスwwwwwうぇwww
0581デフォルトの名無しさん
2005/05/01(日) 06:18:26おまいは全ての関数を値渡しで作るのか?
0582デフォルトの名無しさん
2005/05/01(日) 10:46:33例えポインタがなくても、アドレスをintかlongにキャストして渡せば、同じことが出来る。
手間はかかるが。
0583デフォルトの名無しさん
2005/05/01(日) 15:36:460584デフォルトの名無しさん
2005/05/01(日) 19:18:17アドレスを扱うんならポインタがあった方がいいでしょ
アセンブラじゃないんだし抽象化もされてるし
アドレスを扱わない言語仕様ならポインタも不用だけど
配列も関数も渡すのが難しくなる
0585デフォルトの名無しさん
2005/05/01(日) 20:25:540586デフォルトの名無しさん
2005/05/01(日) 20:30:10環境によってはlongでも死ねる。
0587デフォルトの名無しさん
2005/05/01(日) 20:33:32阿呆だ・・・
0588デフォルトの名無しさん
2005/05/01(日) 23:20:35視点を変えて説明しようとしたんだろう
詰めが甘かったけど
0589デフォルトの名無しさん
2005/05/02(月) 12:32:000590デフォルトの名無しさん
2005/05/02(月) 12:40:560591デフォルトの名無しさん
2005/05/03(火) 19:54:050592デフォルトの名無しさん
2005/05/03(火) 20:02:50int main(int argc, char** argv)
0593デフォルトの名無しさん
2005/05/03(火) 20:05:260594デフォルトの名無しさん
2005/05/03(火) 20:31:18では、具体的にどういう時に使えば便利(に、プログラムが組める)でしょうか?
0595デフォルトの名無しさん
2005/05/03(火) 20:39:57添え字無しで配列が扱えるところ。
えーと、たとえば
forで回してるときは愛があるから配列で・・・
whileで回しているときは愛がないからポインタで・・・
0596デフォルトの名無しさん
2005/05/03(火) 20:53:55俺はこの「char **argv」でCに挫折した。
これは初心者に対するイジメだ。
0597デフォルトの名無しさん
2005/05/03(火) 21:08:45なるほど、そうですか
あんまり、whileを使ったことがなかったですので
新鮮です。
0598デフォルトの名無しさん
2005/05/03(火) 21:10:56ありがとうございました
0599デフォルトの名無しさん
2005/05/03(火) 22:36:57今まで疑問だった部分があっさり氷解した覚えがあるなぁ
あれは感動ものだった…
今ではポインタ無しとか不自由でしょうがない
0600デフォルトの名無しさん
2005/05/04(水) 19:25:45が文字列だってことさえ理解したら
char **
問題ないでしょ?
0601デフォルトの名無しさん
2005/05/04(水) 19:49:220602デフォルトの名無しさん
2005/05/04(水) 20:42:20typedef char ** LPLPCHAR;
と定義すれば分かりやすい。
0603デフォルトの名無しさん
2005/05/04(水) 20:44:35typedef char* PCHAR
typedef PCHAR* PPCHAR
0604デフォルトの名無しさん
2005/05/04(水) 20:48:130605デフォルトの名無しさん
2005/05/04(水) 21:33:28のがいいんじゃない?
0606デフォルトの名無しさん
2005/05/04(水) 21:36:210607デフォルトの名無しさん
2005/05/04(水) 22:28:080608デフォルトの名無しさん
2005/05/04(水) 23:39:38char *が文字列のアドレスを持つ変数の宣言ということはわかる。
しかしchar **が何を意味するのかいくら考えてもわからない。
文字列のアドレスを持つ変数のアドレスを持つ変数宣言?
そうやっているうちにウッキーとなって本を投げて布団かぶって寝る。
0609デフォルトの名無しさん
2005/05/05(木) 03:23:520610デフォルトの名無しさん
2005/05/05(木) 09:04:110611デフォルトの名無しさん
2005/05/05(木) 11:46:18ま、こういうのは例を考えるのが一番
func1(){
char** array_str={
"ぬるぽ",
"ガッ"
};
func2(array_str);
}
func2(char** strings){
printf(*strings); //ぬるぽと表示
*strings++; //次の文字列に変更
printf(*strings); //ガッと表示
}
とすると
func2では、
*stringsでは、呼び出し元の文字列配列の書く文字列を指す。
**stringsでは、各文字をさす
0612デフォルトの名無しさん
2005/05/05(木) 16:09:52例示ありがとう。
でも、んーわからん。
*が二つ以上付くとどういう機能を果たすのか
この根本原理がわからない。
文字列のアドレスを二つ別々に持てる変数…?
*stringsが各文字列を指して
**stringsが各文字を指す…???まるで魔法だ。
やっぱり自分には無理と思う。スレ汚しすまん。
それではさらばっ
0613デフォルトの名無しさん
2005/05/05(木) 16:11:280614デフォルトの名無しさん
2005/05/05(木) 16:16:15機能とか考えてる時点でだめだなw
** でポインタのポインタ
"〜のポインタ"ってだけ
0615デフォルトの名無しさん
2005/05/05(木) 18:59:38初心者の混乱の原因なんだろうね。あと、ポインタと配列を意図的に混合してるのが
紛らわしいのかも。
・Cの文字列の実体は char の配列なんだけど、
簡単に先頭要素のアドレスで表すことが多い (char *)
これが重要
・文字列の配列は、char ary[10][20] とか2次元配列で表現してもいいんだけど
普通は、実体はどっかに作っておいて、先頭要素アドレスの配列であらわす(char *ary[10])
で、main の引数みたいに、「文字列の配列」を他の関数に渡すときの、
呼ばれる側の関数の仮引数は、この場合 char *ary[10] または char **ary となる
0616デフォルトの名無しさん
2005/05/05(木) 19:00:04あと、配列の 『 [] 』 も (ry
0617デフォルトの名無しさん
2005/05/05(木) 19:11:200618デフォルトの名無しさん
2005/05/05(木) 19:18:410619デフォルトの名無しさん
2005/05/05(木) 19:21:330620デフォルトの名無しさん
2005/05/05(木) 20:08:58char *array_str[]じゃないと駄目だろ。
0621デフォルトの名無しさん
2005/05/05(木) 21:36:470622デフォルトの名無しさん
2005/05/05(木) 21:53:340623デフォルトの名無しさん
2005/05/06(金) 01:49:46char *p; // *p は char型
char **pp; // **p は char型
char f(); // f() は char型
簡単だろ。
0624デフォルトの名無しさん
2005/05/06(金) 02:21:560625デフォルトの名無しさん
2005/05/06(金) 02:32:34?
0626デフォルトの名無しさん
2005/05/06(金) 02:53:000627デフォルトの名無しさん
2005/05/06(金) 07:16:47char a;
char ***b=&(&(&a));
みたいな書き方で良いの?なんかキモチワルイ。
0628デフォルトの名無しさん
2005/05/06(金) 09:46:49そうはできない。
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;
こんなんだから混乱するんだよな。
0629デフォルトの名無しさん
2005/05/06(金) 19:35:37とかは?
0630デフォルトの名無しさん
2005/05/06(金) 20:46:58この連休にようやく仕様変更が行われますた。
しかしポインタで宣言した変数には既に前に値が入っていた模様
0631デフォルトの名無しさん
2005/05/06(金) 22:08:56デカチチ = ゴミ
チャパツ = カス
短スカート = アホ
0632デフォルトの名無しさん
2005/05/06(金) 22:10:06&演算子の結果は左辺値ではないので = の左辺には置けない。エラーになる。
ただし大穴としてC++でaが何らかの(非constな)参照型を返すoperaotr &()をオーバーロードしているオブジェクトで、
&bの結果がその何らかの型へ変換できる場合はもちろんコンパイルは通る。
0633デフォルトの名無しさん
2005/05/06(金) 23:14:08と同じことができる言語もあるのにね
0634デフォルトの名無しさん
2005/05/07(土) 12:55:19&a = &b;
なんて真顔で書いてる奴見つけたら、キーボードで殴る
0635デフォルトの名無しさん
2005/05/07(土) 14:26:46おまえら何しゃべってるのか意味がわからん
たのしいけえ?
0636デフォルトの名無しさん
2005/05/07(土) 14:53:520637デフォルトの名無しさん
2005/05/07(土) 15:09:160638デフォルトの名無しさん
2005/05/07(土) 15:45:29C作ったの誰だゴルァ
0639デフォルトの名無しさん
2005/05/07(土) 16:20:25char **b;
char *A=&a,*B=*b;
0640デフォルトの名無しさん
2005/05/07(土) 16:26:56文句あるなら自分で言語作れ。D言語みたいなのは無しの方向で
0641デフォルトの名無しさん
2005/05/07(土) 16:41:09敗残者のスレはここかよ、おぃ(獏称
0642デフォルトの名無しさん
2005/05/07(土) 16:51:190643デフォルトの名無しさん
2005/05/07(土) 16:52:02((void (*)())0)();
0644デフォルトの名無しさん
2005/05/07(土) 16:53:45/** 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;
}
0645デフォルトの名無しさん
2005/05/07(土) 19:33:34アドレスのアドレスってのが
どういう意味なのかさっぱりわからん。
ちょうど三次元の世界に住む俺らが
四次元の世界をイメージするようなもんか。
メモリのアドレスはアドレス一つで一意に決まるんだから
ポインタは*一つの使用法以外にないと思うのだが。
0646デフォルトの名無しさん
2005/05/07(土) 19:47:47*aで受けてa = bとかしても変わらんから
**aで受けて*a = bとかするだろー
そんな複雑なもんじゃないよ
0647デフォルトの名無しさん
2005/05/07(土) 20:02:50『アドレスを格納する変数』 のアドレス
0648デフォルトの名無しさん
2005/05/07(土) 20:41:03なんか、混乱してるようだけど
そんなに難しいもんじゃないよ。
普通のポインタは
int *p
int i
p=&i
なら
ポインタ変数(p) → ポインタにさされる変数(i)
っていう風にさしてるよね?
int **q
int *p
int i
p=&p
q=&p
なら
q → p → i
っていう風にポインタがさしてるだけ。
ただ単に、→が1つ伸びただけ。
0649デフォルトの名無しさん
2005/05/07(土) 20:51:090650デフォルトの名無しさん
2005/05/07(土) 20:56:35ねーよw
0651デフォルトの名無しさん
2005/05/07(土) 21:56:37そもそも642の説明が間違っている。
変数宣言時はこんな意味になる。
* ポインタ変数。(変数のアドレスを格納する変数)
** ポインタへのポインタ変数。(ポインタ変数のアドレスを格納する変数)
どっちも変数のアドレスを格納すると言う点においては何ら変わりない。
0652デフォルトの名無しさん
2005/05/07(土) 22:54:040653デフォルトの名無しさん
2005/05/07(土) 23:16:290654デフォルトの名無しさん
2005/05/07(土) 23:23:22正確にいうと機械語ではなくアセンブラだろ?
0655デフォルトの名無しさん
2005/05/07(土) 23:28:32てのは p がintポインタ型という宣言じゃなくて
*p が int型という宣言だろ。
C++ とかでよくやる
int* p;
て宣言は激しくキモいんだが。
0656デフォルトの名無しさん
2005/05/07(土) 23:32:42>>655自身がキモイ
0657デフォルトの名無しさん
2005/05/07(土) 23:39:01>ら?
アセンブラ
アセンブリ
アセンブル
アセンブレ
アセンブロ
0658デフォルトの名無しさん
2005/05/07(土) 23:39:250659デフォルトの名無しさん
2005/05/07(土) 23:43:580660658
2005/05/07(土) 23:45:53cト 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、 \:::::::::::::::..、 ~" / ヽ.___,./ //ヽ、 ー
0661デフォルトの名無しさん
2005/05/07(土) 23:48:590662デフォルトの名無しさん
2005/05/08(日) 00:25:110と1だけで理解できます。
0663デフォルトの名無しさん
2005/05/08(日) 00:39:560664デフォルトの名無しさん
2005/05/08(日) 00:52:21わしの部屋に監視カメラ付けたのはお主じゃな
0665デフォルトの名無しさん
2005/05/08(日) 01:30:46となりにいる、動物みたいの何?
0666デフォルトの名無しさん
2005/05/08(日) 03:03:32これあんたか?
http://load.satoweb.net/img100/1977.jpg
0667デフォルトの名無しさん
2005/05/08(日) 05:40:19セマンティクスではそうなるけど
キャストなんかでも変数の型としては
int *
とするんだから
0668デフォルトの名無しさん
2005/05/08(日) 07:16:54規格では
・オブジェクト(と関数)を指し示すための値
・ポインタ型として宣言されたオブジェクト
・宣言子中の識別子の前の * と型修飾子の並び
K&Rでは他の変数のアドレスを内容とする"変数"
>>667
セマンティクスでもそうはならない。
宣言子中の * は演算子じゃないし。
てかみんな何で規格書読まないの?
0669デフォルトの名無しさん
2005/05/08(日) 08:38:320670デフォルトの名無しさん
2005/05/08(日) 08:44:03int a, *b, c[10], *d();
なんてできるじゃない?
0671デフォルトの名無しさん
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/
0672デフォルトの名無しさん
2005/05/09(月) 10:58:52見た目が同じってだけ。
*bと同じ見た目の式はint型だけど*bという宣言子はint型でも何でもない。
constを入れてみたら、別のものだってわかると思う。
int * const b;
という宣言は書けるけど、
* const b
なんて式は書けないよね?
0673デフォルトの名無しさん
2005/05/09(月) 11:20:51かけるしょ
0674デフォルトの名無しさん
2005/05/09(月) 11:43:12書けねーよ
0675デフォルトの名無しさん
2005/05/10(火) 06:26:05言っていることがよく分からないのだけど
宣言子をどう解釈するかはコンパイラの仕事であって
それはシンタックスの問題だと思う
人間は「*bがintになるようなポインタ変数なんだな」と
理解して読んでるんじゃないの?
だからaも*bも**cもカンマで区切って並列に記述するのに躊躇しないんだと思うんだけど
0676デフォルトの名無しさん
2005/05/10(火) 06:54:57wwwwwwwwwwwwwおkwwwうはっwwww
おkwwwっうぇwwwwwwwwwwwwwwwwwwwww
wwwwwwwっうぇwwwwwwっうぇ
0677デフォルトの名無しさん
2005/05/10(火) 07:15:10wおkwwwっwっうぇwうぇwwwおkwwwwwwwww
っwwwwwwwwwwww
wうぇwww
っwwwwwwwうはっwwwおkwwwwww
wwwwww
0678デフォルトの名無しさん
2005/05/10(火) 07:51:04wwwwwwっwwwwwwwwwwww
wっうぇ
っうぇっうぇwwwっうぇwwwwwwwwwっうぇ
wwwwwwうはっwwwwwwうぇwwwおkwww
0679デフォルトの名無しさん
2005/05/10(火) 09:57:430680デフォルトの名無しさん
2005/05/11(水) 10:56:27「人間がどう理解するか」なんて話をいつどこで誰がしたんだ?
規格書の意味規則には「*bがintになるようなポインタ変数」に類することは一切書かれていない
だからセマンティクスでも>>655が言ってることは間違い
655みたいな解釈がしたけりゃ勝手にすればいいが、嘘は書くな
0681デフォルトの名無しさん
2005/05/11(水) 14:59:320682デフォルトの名無しさん
2005/05/11(水) 15:11:47void * f(const char * s)
てな感じ。
0683デフォルトの名無しさん
2005/05/12(木) 00:26:25int* b;
b = &a;
int c;
c = *(int*)(unsigned*)(double*)(char*)(long*)b;
if (a==c) puts("別になんともないよ");
こういうのって普通は動作するものなの?
まあ使うこともないんだけど
0684デフォルトの名無しさん
2005/05/12(木) 01:02:26ポインタは、昔のfarなどを除いて、基本的には
どんな型でも、サイズ(sizeof(type*))が同じ
で、型によって、アドレスが変わるって事はないので、問題ない。ハズ
0685デフォルトの名無しさん
2005/05/12(木) 08:30:020686デフォルトの名無しさん
2005/05/12(木) 08:37:04int a=4;
int* b;
b = &a;
int c;
c = *(double*)b;
if ((double)a==c) puts("別になんともないよ");
だったら?
0687デフォルトの名無しさん
2005/05/12(木) 13:16:580688デフォルトの名無しさん
2005/05/12(木) 13:50:08c = *(double*)b;
0689680じゃないよ
2005/05/12(木) 20:35:10こりゃまたトンデモ解釈だな。そんな訳初めて聞いたよ。
Cの作者は、>>675が言うように
>人間は「*bがintになるようなポインタ変数なんだな」と
読ませたかったのかもしれないが、その目論見はどう見ても失敗してて、
こうして混乱してスレ立てたりする奴が出てくるわけだ。
上のような解釈は、既出のようにconstで破綻するし、見ようによっては
関数ポインタでも配列でも破綻する。また、関数の仮引数や、
文字配列の初期化などの例外について、この解釈は何も語ってくれない。
675の言うような解釈を勧めている入門書もあるけど(望洋本とか)
混乱を招くだけだと思うよ。
0690デフォルトの名無しさん
2005/05/12(木) 21:48:38int * const bの宣言はできるが* const bという式はダメという例?
int const bは宣言できるけどconst bという式はないんじゃないの?
0691デフォルトの名無しさん
2005/05/12(木) 21:51:02ポインタの代入じゃないんだけど・・・
ポインタのキャストで指されている変数の型のサイズが広がったらって例です
一部間違い
int a=4;
int* b;
b = &a;
double c;
c = *(double*)b;
if ((double)a==c) puts("別になんともないよ");
ね
0692デフォルトの名無しさん
2005/05/12(木) 21:55:54僕はこれを「人間の解釈」のつもりで使ってきたけど
そうではない用語として使う人もいるってことだね
そのことは理解できました
0693デフォルトの名無しさん
2005/05/12(木) 21:58:47元と同じポインタ型へ戻せば値不変が保証されるらしいから問題ないだろう。
0694698
2005/05/12(木) 23:28:42>int const bは宣言できるけどconst bという式はないんじゃないの?
だから破綻するって言ってるんじゃん。いったい何が言いたいの?
そういや、C++の&でも破綻するよな。
>>692
「意味」とは「人間の解釈」のことである、と認識してる奴は珍しいと思うが。
普通こういう文脈でセマンティクスと言えば、文法よりもうワンランク上のレベルの
「意味論」という意味で、
「それ、文法的にはあってるが意味がないぞ」とか言う場合の「意味」という
言葉に近い意味だと思う。
0695デフォルトの名無しさん
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("この使い方は駄目よ");
あまり、良い例じゃないけどね…
0696デフォルトの名無しさん
2005/05/13(金) 02:10:02たとえばchar*とint*でポインタのサイズが違うような処理系もあったと思うが。
そういう処理系だと、char*からint*にキャストした時点で情報が失われるんじゃ
ないかな。
0697デフォルトの名無しさん
2005/05/13(金) 06:40:26うーん、それじゃ、ポインタ変数の宣言でconstをそこに入れるのと
ポインタ変数を使う場合にconstを入れられないのを例示された意味が分からない
僕が追加したのはポインタ変数でなくても宣言にはconstを入れられるし
変数を使う時には入れられないのだからポインタの宣言についてのみ破綻していると
指摘されるいわれはないということなんだけど
*bがintという意味で
int *b
としてもbを定数と宣言するならbにconstがついて
int * const b
になるのは当然に思うよ
0698デフォルトの名無しさん
2005/05/13(金) 14:36:12聞いた事ないけど、そんな環境があれば、駄目だね
ただ、その場合、
char *cp ;
int *ip ;
cp = malloc ( sizeof(*cp) ) ; /* cpとipでサイズが違うのに */
ip = malloc ( sizeof(*ip) ) ; /* どうやって代入してるの? */
等の処理が特殊であると思われる(ANSI等に準拠してない?)ので、
あまり気にする必要もないかもしれないが…
0699デフォルトの名無しさん
2005/05/13(金) 14:39:25near far は昔あったがなー
0700デフォルトの名無しさん
2005/05/13(金) 16:57:340701デフォルトの名無しさん
2005/05/14(土) 00:05:030702デフォルトの名無しさん
2005/05/14(土) 00:32:01よう分からんけど、それってANSI等の規格に準拠してるの?
まぁ、準拠しているのであれば、>>698の動的確保が上手く行くはずで
内部的にポインタを自動変換する機構を持っているはずなので、
>>695のように、
>代入した時の型と、実際に使う時の型が同じであれば、問題ない
と思うけどね…
>>701
環境次第でしょ
0703デフォルトの名無しさん
2005/05/14(土) 01:28:43準拠してるよ。規格では、異なるオブジェクト型へのポインタのキャストを
認めていて、「与えられた境界調整をもつオブジェクトへのポインタは、
同じか、より制限の弱い境界調整をもつオブジェクトへのポインタに
型変換して、再び元に戻してもよいことを保証する」というところまでは
書いてあるが、境界調整の強い方へキャストして戻ることまでは保証してない。
で、動的確保に関して言えば、あらゆるオブジェクト型へのポインタは
void*にキャストすることとvoid*からキャストすることは認められているから
問題ない。
でも、たとえばchar*をint*にキャストしたら、元には戻らないかも知れない。
0704デフォルトの名無しさん
2005/05/14(土) 02:11:34なるほど
char*やvoid*の方が他のポインタと比べて細かく指定できる
(byteポインタやwordポインタがある)環境では
他のポインタにキャストすると切捨てられる可能性があるって事ね
0705694
2005/05/14(土) 13:44:57>ポインタ変数を使う場合にconstを入れられないのを例示された意味が分からない
しらんよそんなもん。>>672を書いたのは俺じゃないし。
俺が言ってるのは、プログラミング言語の宣言を読むのに、コンパイラの解釈と
違う解釈をしてもメリットはないだろう、ということ。
オブジェクト指向の説明をするのに犬猫ほ乳類を持ち出すようなもの。
まあ、初心者向けのウソを含む解釈が、初心者の助けになるなら
それを使うのもひとつの手だが、少なくともこの例では混乱を招いている
だけじゃないかと。
int array[10];
int *a = array;
みたいなのを見て混乱した、って話がこのスレの上の方でなかったっけ。
確認しないで書いてるけど。
0706680=672だよ
2005/05/14(土) 14:57:58constは「破綻する」例として出した訳ではないんだがな。
破綻する例だとしても一つありゃ十分だろ。
それから、
>>675
>宣言子をどう解釈するかはコンパイラの仕事であって
>それはシンタックスの問題だと思う
コンパイラが何をするものなのか理解してないのか。
単に用語を間違ってるだけか?
宣言子をどう解釈するかはセマンティクスの問題だ。
シンタックスの問題は「それが宣言子であるかどうか」だ。
0707デフォルトの名無しさん
2005/05/15(日) 10:16:200708デフォルトの名無しさん
2005/05/15(日) 10:29:06ポインタでも普通の変数でも同じ状況であるなら
「破綻する」としていることが何か分からないけど
ポインタの宣言においてconstを入れることで破綻することって何なの?
宣言死をどう解釈させたいかはコンパイラの設計者の考えているセマンティクスであって
コンパイラはシンタックスに従って形式的に変換していくだけ
コンパイラの設計者の考えているセマンティクスはコンパイラの動作のためのもので
コンパイラを使うプログラマが考えているセマンティクスとは若干違うね
0709デフォルトの名無しさん
2005/05/15(日) 10:41:33ポインタ渡せば実際の値はコピーされないが、ポインタの値がコピーされますが何か?
int a = 5;
int b = a;
int *p = &a;
これで下の方が早いと思うならまだまだだな
0710デフォルトの名無しさん
2005/05/15(日) 10:53:01まあ確かに
int *a=array;
の例で初心者は混乱するかもしれないね
けどaの宣言をしているんだから初期値の代入をするのはあくまでa
それは宣言以外の式の中で左辺値として使う場合とは違うと認識しなくちゃいけない
int a[3]={1,2,3};
でも定義されているのはあくまでaでしょ?宣言以外の式の中じゃa[3]にこう代入することはできないわけで
0711デフォルトの名無しさん
2005/05/15(日) 10:54:46もっとでかい構造を持った変数とかのことじゃない?そういうのを渡せる言語もあるから
0712デフォルトの名無しさん
2005/05/15(日) 13:54:52ていうかCだって構造体を関数の引数として渡すことできるよな。
だから、ある程度わかっている人同士の会話なら、
「ポインタで渡した方が、値がコピーされない分高速になる」
という言い方で通じるだろうけど、こういうのが現場で「伝承」されていくうちに、
intまでポインタで渡す奴が出てくるというのはありそうな話なわけで… w
0713デフォルトの名無しさん
2005/05/15(日) 19:20:200714デフォルトの名無しさん
2005/05/15(日) 19:23:59>だから、ある程度わかっている人同士の会話なら、
考えるまでもなく、ポインタの方が高速な訳で…
どちらかと言えば、教えた人の言葉の一部分だけを捉えて
勘違いする奴がいるだけではないかと…
0715デフォルトの名無しさん
2005/05/15(日) 19:34:29Win32APIなんかはPOINT(メンバはintが2つ)くらいだと値渡ししている。
0716デフォルトの名無しさん
2005/05/15(日) 19:53:24GetWindowRectとか、受け取るのに構造体使ってるのしか使ったこと無いから知らねぇな・・・
0717デフォルトの名無しさん
2005/05/15(日) 21:20:3364bitの値でlong longを使いたくない(使えない)場合は構造体を使って値渡しやね
0718デフォルトの名無しさん
2005/05/15(日) 21:56:53各手を売った後の盤面の構造体(enum 8×8の配列含む)を値渡ししてたな。
もちろんこれは必要性があってやったわけだけど。
0719デフォルトの名無しさん
2005/05/15(日) 22:18:19うむ。その場合は盤面をまるっと渡したほうが楽だな。
0720デフォルトの名無しさん
2005/05/16(月) 19:11:17同意だが誰がどういう主張をしているのかもう少しちゃんと読め、と。
あと、>>708はもう放っといてやれ
0721デフォルトの名無しさん
2005/05/16(月) 20:04:32#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に確保した領域は自動的に開放される
}
0722デフォルトの名無しさん
2005/05/16(月) 20:16:07されねーよ
ていうかそのまま渡せや
0723デフォルトの名無しさん
2005/05/16(月) 20:16:450724デフォルトの名無しさん
2005/05/16(月) 20:44:18おまえそれ蝶美味しいから
0726デフォルトの名無しさん
2005/05/16(月) 21:04:55bar(b_copy)でいけるしそれで値渡しだと思ってる>>721に蝶ワロス
0727デフォルトの名無しさん
2005/05/16(月) 21:14:44関数宣言は void bar(Board b); だから、
呼び出し側も Board *b_ptr; bar(*b);って補完してねっ☆おねぇさんのお願い
やっぱvoid *calloc(size_t)知らなかっただろ?
この情報は為になりましたか? (●とても役に立った ○大変役に立った)
0728デフォルトの名無しさん
2005/05/16(月) 21:15:52◎ Board *b_ptr; bar(*b_ptr);
0729デフォルトの名無しさん
2005/05/16(月) 21:19:46まぁまぁ、そう慌てなさんなw
0730デフォルトの名無しさん
2005/05/16(月) 21:31:44calloc()が確保したメモリは、
ローカル変数と同じ、スタック上に確保されるんで、
ローカル変数同様、関数を飛び出た直後に解放される
0731デフォルトの名無しさん
2005/05/16(月) 22:24:24>>730
calloc
要素を 0 に初期化した状態で、メモリ内に配列を割り当てます。
alloca
スタックにメモリを確保します。
0732デフォルトの名無しさん
2005/05/16(月) 22:26:390733デフォルトの名無しさん
2005/05/16(月) 22:29:140734デフォルトの名無しさん
2005/05/16(月) 22:33:490735デフォルトの名無しさん
2005/05/16(月) 22:34:39ただのローカル変数の方がずっと良い。
0736デフォルトの名無しさん
2005/05/16(月) 22:38:33さっき書きかけたんだけど、おねぇさんに逆らうスカポンタンが居たから廃棄した
0737デフォルトの名無しさん
2005/05/17(火) 01:07:40今は平気なんだろうけど抵抗あるな・・・
0738デフォルトの名無しさん
2005/05/17(火) 11:54:22今でもデフォルトのスタックはそんなに多くないぞ。
0739デフォルトの名無しさん
2005/05/17(火) 12:15:490741デフォルトの名無しさん
2005/05/18(水) 21:26:180742デフォルトの名無しさん
2005/05/18(水) 22:32:580743デフォルトの名無しさん
2005/05/18(水) 23:54:370744デフォルトの名無しさん
2005/05/20(金) 13:53:020745デフォルトの名無しさん
2005/06/28(火) 23:37:490746デフォルトの名無しさん
2005/06/29(水) 10:48:44ポインタ配列のポインターとして使うのは、わかったのですが他にどう使うのかがわかりません。
たとえば、二分探索木で使われているのですが、これの使い方が理解できません。
0747デフォルトの名無しさん
2005/06/29(水) 11:18:230748デフォルトの名無しさん
2005/06/29(水) 15:00:50するとyはxのポインタ、つまりポインタのポインタである。
って事はどうなるの
↓
0749デフォルトの名無しさん
2005/06/29(水) 15:38:39char *strings;
};
structure_def *structure;
0750デフォルトの名無しさん
2005/06/29(水) 15:59:27char 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);
0751デフォルトの名無しさん
2005/06/29(水) 20:29:020752デフォルトの名無しさん
2005/06/29(水) 22:56:56それはともかくとして、「引数」に値を代入したいときにはポインタにする。
void f1(int *a, int b)
{
*a = b;
}
その「引数」の型がたまたまポインタだったりすると結果はポインタのポインタになる。
void f2(int **a, int *b)
{
*a = b;
}
ようするにそれだけなんだけどね。
0753デフォルトの名無しさん
2005/06/30(木) 02:24:28ボインタのボインタが必要ってことね。
0754デフォルトの名無しさん
2005/06/30(木) 06:11:01ポインタを参照渡ししたいなら、な
0755デフォルトの名無しさん
2005/06/30(木) 10:48:17char* 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);
0756デフォルトの名無しさん
2005/07/01(金) 14:17:27全ての変数を**************つけて定義してみた。
コンパイルしてバイナリ(obj)比較したら変わらんかった。
& -1 * +1 [] +1という感じで差を数えてたのかな。
0757デフォルトの名無しさん
2005/07/02(土) 23:47:200758デフォルトの名無しさん
2005/07/02(土) 23:59:46たとえばこんなとき。
#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ポインタを使う。)
0759デフォルトの名無しさん
2005/07/03(日) 01:29:03x = new double[n][m];
ってアリですか。
ナシなら2次元の場合どうしたらシアワセになれますか
0760デフォルトの名無しさん
2005/07/03(日) 02:05:40#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;
}
0761760
2005/07/03(日) 02:10:13delete[] x[j];
0762デフォルトの名無しさん
2005/07/03(日) 02:18:170763デフォルトの名無しさん
2005/07/07(木) 16:00:310764デフォルトの名無しさん
2005/07/07(木) 16:21:461000以下の素数を求めて、足したら1000になる組み合わせを探す
0765デフォルトの名無しさん
2005/07/07(木) 17:54:37マルチすんな。
0766デフォルトの名無しさん
2005/07/07(木) 19:17:350767デフォルトの名無しさん
2005/07/07(木) 21:44:000768デフォルトの名無しさん
2005/07/07(木) 21:48:210769デフォルトの名無しさん
2005/07/07(木) 21:58:58x = 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;
0770デフォルトの名無しさん
2005/07/07(木) 22:12:50それは効率が悪くないか?
ゴールドバッハの予想を使えば少し効率良く処理できるかと。
0771デフォルトの名無しさん
2005/07/08(金) 01:48:06真実
アセンブラでできることをシンプルに実装してるからなCは
0772日本道路公団
2005/07/08(金) 02:46:050773デフォルトの名無しさん
2005/07/08(金) 03:22:24http://www5e.biglobe.ne.jp/~liquor/raytrace/
http://www5e.biglobe.ne.jp/~liquor/prime/
0774デフォルトの名無しさん
2005/07/08(金) 03:46:00意外とおもしろいのがインラインアセンブラ
0775デフォルトの名無しさん
2005/07/08(金) 19:43:52オ-バー風呂-とか消えてしまない?
Cは何かと不便なきが。
0776デフォルトの名無しさん
2005/07/08(金) 20:13:11まずはそのダメダメな日本語を消さないとな
0777デフォルトの名無しさん
2005/07/09(土) 04:36:01リストやソートや検索のお勉強で脳ミソからお熱をあげる人(おれ)ってプログラミング向いてない?
ポインタはなんとかクリアしたはずなのにな
0778デフォルトの名無しさん
2005/07/09(土) 14:38:49最初は誰でもそう。
初めから全部わかったら天才か基地外。
0779デフォルトの名無しさん
2005/07/09(土) 22:01:170780デフォルトの名無しさん
2005/07/09(土) 22:30:420781デフォルトの名無しさん
2005/07/10(日) 14:57:46エロい表現ですね
0782デフォルトの名無しさん
2005/07/13(水) 14:33:50嫌がおうにもポインタを使ってしまう体になる。
0783デフォルトの名無しさん
2005/07/13(水) 23:49:21あまりエロくない表現ですね
0784デフォルトの名無しさん
2005/07/15(金) 00:43:49ポインタ使ってスパゲッティなコード書くよな
0785デフォルトの名無しさん
2005/07/15(金) 07:51:23_, ._
( ゚ Д゚) ・・・
_, ._
( ´ Д⊂ ゴシゴシ
_, ._
( ゚ Д゚) ・・・
0786デフォルトの名無しさん
2005/07/15(金) 16:34:34ていうかボインタって何ですか?調べたけど解りませんでした
0787デフォルトの名無しさん
2005/07/15(金) 18:10:100788デフォルトの名無しさん
2005/07/15(金) 20:29:410789デフォルトの名無しさん
2005/07/15(金) 20:30:400790デフォルトの名無しさん
2005/07/20(水) 23:45:090791デフォルトの名無しさん
2005/07/20(水) 23:56:420792デフォルトの名無しさん
2005/07/31(日) 11:02:210793デフォルトの名無しさん
2005/08/06(土) 07:45:540794デフォルトの名無しさん
2005/08/19(金) 23:43:460795デフォルトの名無しさん
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にアクセスしてるかどうかはわからんのだが。
0796795
2005/08/20(土) 00:11:18↓2293596番目
┏━━━━━━━━━━━━━━┓
┃ 〜 100 〜 ┃ ←この四角いのがメモリ
┗━━━━━━━━━━━━━━┛
0 536870912(512MB)
0797デフォルトの名無しさん
2005/08/20(土) 03:06:45別に三角形でもいいじゃないか。
0798デフォルトの名無しさん
2005/08/20(土) 06:10:58分かりやすい
変数をメモリ以上使ったらどうなりますか?
0799デフォルトの名無しさん
2005/08/20(土) 06:15:150800デフォルトの名無しさん
2005/08/20(土) 15:01:43>おまえのマシンに512MBのメモリが刺さってたら、
>ポインタってのは 0〜536870912(512MB) の範囲のメモリ位置をあらわす数値なんだよ。
2.
>まあ、今時のOSはみんな仮想メモリだから、
>実際の物理的なメモリの2293596にアクセスしてるかどうかはわからんのだが。
2.があやふやだから、1.がおかしい
プロテクトモードでも、セグメント切り替え、64kの壁て知ってるか?
と、初歩向けの答えに突っ込みを入れてみるw
0801デフォルトの名無しさん
2005/08/20(土) 15:19:33MMUは変数をメモリ以上使わなくとも使っている、プロテクトモードなら。
そもそもMMUは、物理メモリを論理メモリに変換するCPUの機能
何故、そんなことをするかというと、
・システムとして重要なアドレスエリアをユーザに使われないようOSがプロテクトモードの階層(権限)(Penに設定できるレジスタがあったと思う)により制限を掛けるため。
(もし、アクセスするとアドレス保護例外(CPUが出す例外)が起こる)
・プログラム同士のアドレスをお互いに侵食しないために利用アドレスを分けている。
(プロテクトモードでユーザから見て0番地でも、実際は全く違う。更に言うと、ユーザから見て0番地が多数存在する)
あとは、IDT(割り込みベクタテーブル)のCPUの外から見える存在アドレスを変えることにより、
独自に(OS上に)割り込みベクタテーブルをカスタマイズできるというのもある
それと、これはMMUでなく、プロテクトモードの機能だけど、階層(権限)により、システム上重要なアセンブラ命令をユーザに使わせないようにしている>特権命令(OSが設定)
0802795
2005/08/21(日) 01:23:36!?なんて柔軟な発想!
>>798
あなる程・・・アナル程・・・。
えーっと、しらん。なんか仮想メモリ的なものでがんばるんじゃないか?
>>800
1.がおかしいのは説明用の文章だから。
2.があやふやなのは、漏れがそこまで仮想メモリについての知識を持ってるわけじゃないから。
0803795
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)
0805デフォルトの名無しさん
2005/08/21(日) 13:10:27あ?
あせって書かなくていいんだよ。
だいたいなんで、
int* ap = &a
とポインタ参照なのに、先頭アドレスが違ってるんだ、そこでおかしいと思わなかったか?
で、&apてなんだ?
変数aの指す先頭アドレスは&a
変数apの指す先頭アドレスはapだろう
apにある値は*apだろう
図が無茶苦茶だなぁ
0806795
2005/08/21(日) 14:58:55ん?どのへんがわからないんだ?
>変数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
0807795
2005/08/21(日) 15:09:03int 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*にキャストしてるのはえーと説明めんどい。
0808つりじゃないか?
2005/08/21(日) 15:17:59さきと変わたな。
>int* ap = &a;
が
>int ap = (int)&a;
になった。
つりだとおもうけど、さっきと状況一変したぞ。
今度は参照ではない。単にアドレス値をint型へ代入してる。
だから、&aと&apのアドレスが違う。
それと、
さきの&apてなんだ?だが、
int* ap
と宣言しておいて、int**を求めるいうことか?
これは何を意味するのか分からない、 俺の脳みそが足らないだけかもしれないけど。
0809795
2005/08/21(日) 15:35:05うーん、そうだな。最終的にポインタ型もデータなのよ。メモリにデータとして確保される。
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番目)が返ってくるわけよ。
上に書いたコードをコンパイルして色々試してみるとわかるよ。
0810デフォルトの名無しさん
2005/08/21(日) 15:37:16そもそもポインタは、アドレスを格納するだけのものではない。
型付けという重要な役割を持っている。
0811795
2005/08/21(日) 15:38:37○つまり、ポインタを宣言するのは 4byteの整数型を宣言すると一緒なのよ
の方がわかりやすいかね。
0812デフォルトの名無しさん
2005/08/21(日) 15:42:47つまり、宣言によって、ある一定サイズのメモリエリアが確保されるという意味においては、
ポインタ型も他の組み込み型といっしょなのよ。
というべきだ。
0813795
2005/08/21(日) 15:48:03まあ、たしかにね。「初歩を理解する上では」という意味で説明をしたわけよ。
「型付け」に関してもまず何が入っているか説明した方がわかりやすいだろうし。
それに処理系を限定して具体的な話をしたほうがわかりやすいだろ。
なぜポインタが4バイトなのかは、32bit(4bytes) CPUだから4バイトが扱いやすいとか、
今の4バイトのポインタでは、4バイトで表現できる最大の4ギガ(4294967296)までが、
扱えるメモリの限界とか色々まわりのこともわかってくるわけだし。
0814795
2005/08/21(日) 15:54:38あっ、>>812えーと。そうだね。でもそれだと初心者は意味わかんなくね?
だから、>>1みたいなまだ理解が浅い人が、
そういう抽象的な説明をされて意味わからなくてこういうスレを建てちゃうわけよ。
0815デフォルトの名無しさん
2005/08/21(日) 15:58:23現在多く普及しているWindowsでは、どちらも32bitであることが一般的である。
ここでは、特に断りない場合intやポインタ型は32bit(4bye)として話を進める。
と最初にかいときゃいいじゃん。むしろこういうのが一番大事。
0817デフォルトの名無しさん
2005/08/21(日) 16:18:10それは違うだろう
>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)でもどちらでもこのまま試せる
0818デフォルトの名無しさん
2005/08/21(日) 16:29:20#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の内容は"あい"のままになる。
0819795
2005/08/21(日) 16:33:42ん?そうではないとすると、じゃあ↓これはどう説明するんだ?
#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);
}
0820デフォルトの名無しさん
2005/08/21(日) 17:59:36void 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**が分かんないなぁ
こんな程度ですまないね
0821デフォルトの名無しさん
2005/08/21(日) 18:39:25Pentiumの持ってるアドレッシング方式と、OSがコードを翻訳したとき放つ命令セットを分かってないけど
&bが4byteスライドして動いている
0822デフォルトの名無しさん
2005/08/21(日) 18:42:59>OSがコードを翻訳
>コンパイラがコードを翻訳
0823デフォルトの名無しさん
2005/08/21(日) 19:26:05int*でebp(ベースアドレス)+esi(インデックス)を表し
int**でebp(ベースアドレス)を表すんじゃないかなと思た
32bitの場合にはesiで4byteじゃないかなと
int** c=&b;
でベースインデックスアドレス指定だったのが
*c=&a2;
でベースアドレスをしていていて、それでアドレスが4byte動いたのかなと
推測ですみませんね
違っていて、もしよかったら指摘してください
0824マイク ◆yrBrqfF1Ew
2005/08/21(日) 19:32:440825795
2005/08/21(日) 22:47:25int 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) と等価になる。
0826795
2005/08/21(日) 22:49:15int 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
レジスタとかわからんちん。
0827795
2005/08/21(日) 22:50:440828795
2005/08/21(日) 23:22:16MSのC言語とかGCCのC言語による、ポインタの実装であって、
C言語の仕様としてはポインタは整数値で管理しているとは記されてはいないというのを読んだことがあるけど。
・・・って >>532 ここかぁー!
でも今後、新しいCコンパイラが出たとしても、
このポインタを「メモリアドレスを格納する整数値」で実装する方法は変わらないでしょうね。
大体のコンパイラでは、こういう実装なのに>>532みたいな発言するのは初心者が混乱するんでやめてほしい。
0829デフォルトの名無しさん
2005/08/21(日) 23:26:25ポインタがアドレスである必要はないし、むしろそういう規定は柔軟性を損なわせる。
0830795
2005/08/21(日) 23:38:18(;・∀・)ちゅ、中間言語・・・?Javaのようになるん!?
ぼくのしってるgccもかわっちゃったなぁ。というか最近のC言語もすごいなぁ。
そうなると俺もC言語のポインタってなんですか?っていうスレたてちゃうかも('A`)
0831デフォルトの名無しさん
2005/08/22(月) 00:02:22中間言語の存在はコンパイル中だけで出力されるオブジェクトファイルは機械語だよ。
0832デフォルトの名無しさん
2005/08/22(月) 11:38:24中間言語(仮想コード)にするのは 4.0 以前からやっていた筈だけど?
4.0 は各言語に合わせた最適化をするようになったんだと思った。
0833デフォルトの名無しさん
2005/08/22(月) 13:23:270834デフォルトの名無しさん
2005/08/22(月) 14:06:151冊ではありません。amazon.co.jp で「C ポインタ」をキーにして
和書の検索をすると17冊出てきます。
0835デフォルトの名無しさん
2005/08/22(月) 14:20:060836デフォルトの名無しさん
2005/08/22(月) 14:21:460837デフォルトの名無しさん
2005/08/22(月) 14:32:12文字列の配列とかで使いますね。
例
char *s[] = {"Hello", "2ch"};
0838デフォルトの名無しさん
2005/08/22(月) 14:55:290839デフォルトの名無しさん
2005/08/22(月) 20:25:23たとえばこんな感じに。
void GetMem(void **pp)
{
*p = malloc(0x100);
}
別に普通の型へのポインタと変わらない。
void GetRand(int *p)
{
*p = rand();
}
0840デフォルトの名無しさん
2005/08/22(月) 22:29:06クラスのメンバ関数の関数ポインタ型の定義を書けと言われて
即時答えられる奴は少ない
0841デフォルトの名無しさん
2005/08/22(月) 23:14:26そこにコンパイラがあればささっと書くだけ。
#include <iostream>
#include <typeinfo>
struct hoge
{
void f();
};
int main()
{
std::cout << typeid (&hoge::f).name() << std::endl;
}
0842デフォルトの名無しさん
2005/08/23(火) 00:08:09たしかに。定義としかも呼び出し方法も即答できないね。あれは。
Klass k;
void (Klass::*aho)(void) = &Klass::method;
((k).*aho)(); // インスタンスにメソッドポインタを関連付けて呼び出し
こりゃねえだろ → ((k).*aho)()
それとも、もっと簡単にかける?
0843デフォルトの名無しさん
2005/08/23(火) 00:09:32(k.*aho)()
0844デフォルトの名無しさん
2005/08/23(火) 00:15:28まじだ。できた。
それでもまだ数日後に覚えていられるかは微妙(笑
0845デフォルトの名無しさん
2005/08/23(火) 00:40:09fp();
と
(*fp)();
のどっちでもコールできるの知らないのか?
0846デフォルトの名無しさん
2005/08/23(火) 01:00:59.と*の二つで.*となって一つの演算子。->*は三つで一つの演算子。
というように覚えると早い。->が-と>に分けられないのと同じで。
0847デフォルトの名無しさん
2005/08/23(火) 08:57:03普通の関数ポインタはそうなんだが、C++のメンバへのポインタを使って関数呼び出しするときには844のようにするしかない。
0848デフォルトの名無しさん
2005/08/24(水) 01:49:44それは知ってる。
むしろ
(******************fp)();
でも呼べるのも知ってる。
>>846
おお、それはおぼえやすいかもしれん。
0849デフォルトの名無しさん
2005/08/24(水) 19:12:290850デフォルトの名無しさん
2005/08/25(木) 22:12:50意味無いけどオーバーロードできるし。
0851デフォルトの名無しさん
2005/08/25(木) 22:21:55.*はオーバーロードできない。 . もオーバーロードをできないからそれに合わせて。
0852デフォルトの名無しさん
2005/08/27(土) 14:43:06ポインタという変数のアドレスへのポインタはどの変数が持っているの?
0853デフォルトの名無しさん
2005/08/27(土) 15:09:57変数を使ったコードで命令と一緒にパラメタとして使われてる。
0854デフォルトの名無しさん
2005/08/27(土) 18:32:460855デフォルトの名無しさん
2005/08/27(土) 18:51:56別にポインタって型が必要といわけでは無いのだが、
ポインタって型がないとポインタと単なる整数の区別がつかなくてさらにバグを生み出す原因に
0856デフォルトの名無しさん
2005/08/27(土) 18:55:30大量のデータが必要でも、動的に確保できるので、実行時に使用するメモリを減らせる。
また、サイズの変更が容易になる。
大量のデータでもアドレス計算を少なくして処理できる。
アドレスを単純に増加させてもオフセットの取り方で連続したメモリにならない。
その境界部分の演算が遅くなる原因になるがポインタを使えば境界を越える演算が減らせる。
コード記述で、名前に依存しない記述が可能になる。
同じ関数内で少ないコードで多彩な動作が可能になる。
こんなところだと思う。
0858デフォルトの名無しさん
2005/08/29(月) 08:45:500859デフォルトの名無しさん
2005/08/29(月) 08:57:19勝手に型をつけてくるのは、場合によっては邪魔になることもあるが。
0860デフォルトの名無しさん
2005/08/29(月) 16:44:000861デフォルトの名無しさん
2005/08/29(月) 16:47:540862デフォルトの名無しさん
2005/08/29(月) 16:53:46いや、画像処理とかで使いまくりなんだが
0863デフォルトの名無しさん
2005/08/29(月) 19:17:52解説する人間の数だけ増えるポインタの例え方
クラスにも通じる物がありますね
0864デフォルトの名無しさん
2005/08/29(月) 21:19:27「オブジェクト指向」って言葉には殆ど意味なんてないし。
OOAとかOOPとか、後に何か付いてやっと意味になる。
0865デフォルトの名無しさん
2005/08/29(月) 21:47:0332bit用コンパイラでもポインタのサイズ全部が32bitだと思ったら大変危険。
>860
C言語の仕様だとおもう。
0866デフォルトの名無しさん
2005/08/30(火) 09:55:15Linuxは全部こうなんだけど、そろそろどうなんだろうね
0867デフォルトの名無しさん
2005/08/30(火) 16:31:57そんなソースコードいやぽ(;´Д`)
0868デフォルトの名無しさん
2005/08/30(火) 16:37:13しょうがないよ
マジだもん
0869デフォルトの名無しさん
2005/08/30(火) 17:16:250870デフォルトの名無しさん
2005/08/30(火) 18:59:49Linuxの何が「こう」なの?
0871デフォルトの名無しさん
2005/08/30(火) 19:09:290872デフォルトの名無しさん
2005/08/30(火) 19:48:14ポインタとかアドレスを unsigned long と扱うコード
0873デフォルトの名無しさん
2005/08/30(火) 20:42:24なんでそんなことになってんの?
メリットは何?
0874デフォルトの名無しさん
2005/08/30(火) 20:52:05今となってはもはや昔ながらの伝統以外の意味は全くない
0875デフォルトの名無しさん
2005/08/31(水) 16:54:40全部ってこたねえだろう。
0876デフォルトの名無しさん
2005/09/25(日) 02:53:100877デフォルトの名無しさん
2005/09/25(日) 09:58:37>>758
0878デフォルトの名無しさん
2005/10/01(土) 21:46:450879デフォルトの名無しさん
2005/10/01(土) 21:48:490880デフォルトの名無しさん
2005/10/02(日) 15:41:450881デフォルトの名無しさん
2005/10/04(火) 12:52:030882デフォルトの名無しさん
2005/10/07(金) 01:18:25ポインタはね、関数で複数の戻り値を返したい時にとても便利なんだお。
普通はreturnで一個しか返せないんだお。
0883デフォルトの名無しさん
2005/10/07(金) 18:28:57構造体
0884デフォルトの名無しさん
2005/10/08(土) 09:43:23戻り値は構造体のポインタであって
構造体そのものではない罠
0885デフォルトの名無しさん
2005/10/08(土) 09:51:210886デフォルトの名無しさん
2005/10/08(土) 12:09:06構造体は返せない。
構造体のポインタは返せるが。
構造体と構造体のポインタは別物。
0887デフォルトの名無しさん
2005/10/08(土) 12:16:300888デフォルトの名無しさん
2005/10/08(土) 12:19:06嘘教えるより100倍マシだと思うけど…
0889デフォルトの名無しさん
2005/10/08(土) 12:19:270890デフォルトの名無しさん
2005/10/08(土) 12:20:270891デフォルトの名無しさん
2005/10/08(土) 12:20:48構造体を返すプログラムのソース挙げて見れ。
0892デフォルトの名無しさん
2005/10/08(土) 12:20:570893デフォルトの名無しさん
2005/10/08(土) 12:23:29int a,b,c,d;
} E;
E foo(E ee){
return ee;
}
0894デフォルトの名無しさん
2005/10/08(土) 12:27:18構造体は返せるし渡せるようになっているんだけど
> 嘘教えるより100倍マシだと思うけど…
などと言いながら、平気でウソを教える。
だから「老害」なんだよ。
0895デフォルトの名無しさん
2005/10/08(土) 13:03:150896デフォルトの名無しさん
2005/10/11(火) 02:43:490897デフォルトの名無しさん
2005/10/11(火) 02:58:09一般的な実装では、暗黙の第一引数として呼び出し側がアドレスを渡して
そこに代入するんだけどな。
あと、レジスタで渡せるサイズだったらレジスタで返す実装もあった。
もちろん、渡す場合は全コピーだけど。
0898デフォルトの名無しさん
2005/10/11(火) 03:38:37実体を返してみたら、実行速度が物凄く遅くなってワロタ。
Cでも配列を実体で返せる方法だと、馬鹿そのものの歓び方をした。
0899デフォルトの名無しさん
2005/10/11(火) 11:55:040900デフォルトの名無しさん
2005/10/11(火) 19:25:37いや、なんとなく
0901デフォルトの名無しさん
2005/10/11(火) 19:43:460902デフォルトの名無しさん
2005/10/11(火) 19:50:43そりゃ大変だな…
0903デフォルトの名無しさん
2005/10/12(水) 02:57:010904デフォルトの名無しさん
2005/10/12(水) 03:54:540905デフォルトの名無しさん
2005/10/12(水) 04:15:24しかし16bitアプリでは二つのポインタが!!
0906デフォルトの名無しさん
2005/10/12(水) 04:19:410907デフォルトの名無しさん
2005/10/12(水) 08:28:080908デフォルトの名無しさん
2005/10/12(水) 16:28:10寝言は寝て言え
0909デフォルトの名無しさん
2005/10/17(月) 04:07:53int* p; でも int *p; でも好きにすりゃええやん。
0910デフォルトの名無しさん
2005/10/18(火) 19:37:20ANSI 以前の C でも構造体は返せるようになっていた。
しかしその後流行出したPCでのCコンパイラの実装では
使えないようになっているサブセットのやつが多かった。
実際使うと恐ろしく遅くなることがあって、使えても
使う人は少なかったのではないかと思う。
0911デフォルトの名無しさん
2005/10/18(火) 21:00:350912デフォルトの名無しさん
2005/10/18(火) 21:01:300913デフォルトの名無しさん
2005/10/18(火) 21:15:560914デフォルトの名無しさん
2005/10/18(火) 21:46:57>>895
0915デフォルトの名無しさん
2005/10/18(火) 22:43:05以下ループ
0916デフォルトの名無しさん
2005/10/19(水) 08:37:19呼び出し側のスタックに直接書き込む言語もあったりするな。
0917デフォルトの名無しさん
2005/10/19(水) 14:17:10最適化具合でそうなるコンパイラもありえるんじゃね?
レス数が900を超えています。1000を超えると表示できなくなるよ。