約 3,372,791 件
https://w.atwiki.jp/sevenlives/pages/495.html
ポインタ 読み:ぽいんた 英語:pointer 別名: 意味: ポインタとはなんらかの値を持つ変数に対し、位置情報から間接的に変数を操作する仕組みのこと。 ポインタをでメモリのアドレスを直接操作できることで細やかなハードウェア制御ができる反面、バッファ・オーバーランなどの危険性も秘めているので、比較的新しい言語ではこのポインタの機能を付けていない物が多い。 2015年10月02日 間接参照演算子? アドレス(メモリ) ポインタ型? ポインタ演算? アドレス演算子? シンボル 関数ポインタ? ヌルポインタ? ダングリング・ポインタ? バッファ・オーバーラン?
https://w.atwiki.jp/genshiken/pages/25.html
ポインタ ポインタとは ポインタとは、値のアドレスを保持するための変数です。 ポインタの宣言 ポインタ型を表すには、「*」を使います(*はクリーネスターとかいうこともあります)。 int * ptr_int; /* ptr_int は int 型の値へのアドレスを保持するポインタ */ int ** ptr_ptr_int; /* ptr_ptr_int は int 型のポインタのポインタ */ 値とアドレス すべての値にはアドレスが存在します。勿論ポインタにも存在します。 アドレスとはその値の存在する場所を表す整数値です。 アドレスを取り出すにはアドレス演算子「 」を使います。 int num = 0; int *ptr = num; アドレスのさしている値を取り出す時は、間接演算子「*」を使います。 *ptr = 1; /* num には 1 が代入される。ptr 自体は変化しない */ 関数ポインタ 関数のアドレスを保持するポインタを、関数ポインタと呼ぶ。 これにより、関数の実体を持ち運ぶことはできないが、それを擬似的に再現することができる。 (実体を持ち運ぶ必要性はほとんどの場合ないのでこれで充分) int 型の引数を取り、int 型を返す関数のポインタは以下のように宣言される。 int (*func_ptr)(int); 以下のように使用する。 int add_one(int n){ return n + 1; } int (*func_ptr)(int); func_ptr = add_one; int i = (*func_ptr)(1); /* i には 2 が代入される */ 関数のアドレスは、アドレス演算子を使わなくても得る事ができる。 また、関数ポインタ越しに関数を呼ぶこともできるため、上のコードは以下のように書き換えることができる。 func_ptr = add_one; int i = func_ptr(1); 初心者は分からなくてもいいです。 ゲームプログラミングにおいては、タスクシステムなどで使用することはあるものの、なければならないということはないです。
https://w.atwiki.jp/slimelv1024/pages/57.html
ポインタとは アドレスを記憶する変数です ポインタを話す上でこれは欠かせない要素なのでよく覚えていてください ポインタはアドレスを記憶し間接的にメモリを参照することが出来ます メモリ上のアドレスを指定してあげることで間接的に変数や配列の操作を行うことが出来ます アドレス アドレスとはメモリ上の番地のことです プログラムもデータもこのメモリ上のアドレスに記憶されています 今まで使ってきた変数や配列はメモリ上に割り振られ、それぞれのアドレス持っています それぞれの領域は型のデータサイズに依存し、char型なら1バイトの領域を占め、int型の要素数3の配列なら12バイトの領域を占める 変数や配列のアドレス int a=123; char str1[]="ABC"; char str2[][7]={"TANAKA", "SATOU", "SUZUKI"} printf("a=%d\n",a); printf(" a=%p\n", a); printf("\n"); printf("str1=%p\n",str1); printf("str1[0]=%c\n",str1[0]); printf("str1[1]=%c\n",str1[1]); printf("str1[2]=%c\n",str1[2]); printf(" str1[0]=%p\n", str1[0]); printf(" str1[1]=%p\n", str1[1]); printf(" str1[2]=%p\n", str1[2]); printf("\n"); printf("str2=%p\n",str2); printf("str2[0]=%p\n",str2[0]); printf("str2[1]=%p\n",str2[1]); printf("str2[2]=%p\n",str2[2]); printf("str2[0][0]=%c\n",str2[0][0]); printf("str2[1][0]=%c\n",str2[1][0]); printf("str2[2][0]=%c\n",str2[2][0]); printf(" str2[0][0]=%p\n", str2[0][0]); printf(" str2[1][0]=%p\n", str2[1][0]); printf(" str2[2][0]=%p\n", str2[2][0]); 指定している変数は同じなのに値が違って出てきます これは でメモリ上のアドレスを指定しているからです (アンパサンド)はアドレス演算子と呼ばれ、変数のアドレスを取り出します プログラマにはどこのアドレスに変数が割り当てられたのか分からないので、アドレスを求めるためにアドレス演算子を使います scanfで使う も同じでアドレスを渡していたのです 変数名 変数の値 変数 変数のアドレス 配列名 配列の先頭アドレス 配列名[添字] 配列要素の値 配列名[添字] 配列要素のアドレス 配列名 配列先頭アドレス 配列[行] 行の先頭要素のアドレス 配列[行][列] 配列要素の値 配列名[行][列] 配列要素のアドレス 一次元配列のアドレスを見てもらえると分かりやすいと思いますが、配列のアドレスは並んでいます 配列は必ず並びでアドレス領域が確保されます これは二次元配列でも同じです puts関数とgets関数 入出力の項で少しだけ触れたこの関数ですが、二つとも引数でアドレスを受け取れるように出来ています char str[256]; puts("文字列を入力してください") gets(str); puts(str); ポインタ 一番最初に書きましたがポインタとはアドレスを記憶する変数です 今まで数字や文字を記憶するのに変数を使って来ました それと同じように変数のアドレスを記憶するのがポインタ変数なのです しかし、ポインタの意義はこの記憶されているアドレスを使って間接的にメモリを参照することです ちょっとややこしいですが、一つ一つ確認していきましょう ポインタの宣言 ポインタも変数なので宣言する必要があります データ型* ポインタ名; データ型 *ポインタ名; どちらも同じポインタ変数の宣言です 人によって宣言の仕方は違うので両方覚えておきましょう ここで使われてる*はポインタ宣言子と呼ばれます アドレスの代入 当然ポインタも変数なので宣言しただけでは中に不定値が入っています ポインタの変数名= 代入する変数名 先ほどの宣言とは違い、扱いは変数なのでここでは*は尽きません しかし、ポインタが記憶できるのはアドレスなので、代入する変数には を忘れないでください 変数とは少し扱いが違いますが、ここまでがポインタ変数の下準備です メモリの参照 *ポインタ名 ここで使われている*は間接参照演算子と呼ばれおり、ポインタの指すアドレスの中身を表します ポインタの宣言のときにも使いましたが、あの*とはまったくの別物です また、計算式のとき乗算として扱われる*とも別物です 乗算演算子とポインタ宣言子、間接参照子の三つの意味合いが*にあるのを覚えておきましょう ポインタの簡単な使用例 言葉だけでは分かりにくいと思うので実際にプログラムとして動かしてみましょう int num=100; int *p1,*p2; //ポインタの宣言 p1= num; //p1にnumのアドレスを代入 p2=p1; //p2にp1のアドレスを代入 *p2=*p1+1; //p1の指すアドレスの中身参照し、参照した値+1をp2の指すアドレスの中に代入 printf("numの値は%d numのアドレスは%pです\n",num, num); printf("*p1の値は%d *p1のアドレスは%pです\n",*p1,p1); printf("*p2の値は%d *p2のアドレスは%pです\n",*p2,p2); 実行結果 numの値は101 numのアドレスは01EFD84です *p1の値は101 *p1のアドレスは01EFD84です *p2の値は101 *p2のアドレスは01EFD84です すべて同じ値とアドレスが出てきたと思います(アドレスの出す値は環境によって変わります p2はp1のアドレスを記憶し、p1はnumのアドレスを記憶しています p2のアドレスの指す中身はp1であり、p1のアドレスの指す中身はnumなのです つまりp2は間接的にnumの100を取得し、間接的にnumの値を変えることが出来たのです ポインタと配列 配列の場合もポインタの宣言、アドレスの代入、アドレスの参照を必ず行います ただし、配列の場合参照する方法が二種類あります char name[7]="TANAKA"; char *p1,*p2; int i; p1=name; p2=name; for(i=0;*(p1+i)!=\0;i++){//方法1 printf("%c",*(p1+i)); } while(*p2!=\0){//方法2 printf("%c",*p2); p2++; } 方法1はポインタの値を変えずに参照しています この書き方で注意しなければならないのは()です ()を忘れると*p1にiを代入すると言う式になってしまいます 方法2はポインタの値を変えて参照しています こちらの方法は値を更新してしまっているため、もう一度使うときに更新したポインタを元に戻さないと、別のエリアを参照してしまいます 参照だけならいいですが、書き込みだった場合別のエリアのデータを破壊してしまいますので、注意が必要です ポインタと文字列リテラル 配列の項で文字列は書き換えることが出来ないと説明しましたが、ポインタを使うことで文字列を書き換えることが可能です char *p; p="ABC" このABCというのはメモリ上のどこかに用意された文字列です 文字列の先頭アドレスを取得することで、文字列の情報を入手することが出来ます つまりポインタが記憶する文字列の先頭アドレスを変えれば、文字列を書き換えることが出来るのです ポインタの配列 ポインタでも配列を扱うことが出来ます データ型 *配列名[要素数] 複数の文字列は二次元配列で扱っていましたが、ポインタの配列を使うと一次元配列で扱うことが出来ます char *p[3]={"abc","defghi","jk"}; puts(str[0]); puts(str[1]); puts(str[2]); 二次元配列と違い確保した空いてるスペースにNULL文字を入れる必要がない代わりに、文字列が並びで確保されず、文字列の先頭アドレスを記憶する領域が必要になるため、どちらを使うかは二つの特色を考えて選択しましょう
https://w.atwiki.jp/tetdm/pages/22.html
アドレス演算子 #include stdio.h main() { int x = 10; printf("%p\n", x); } ポインタ変数 #include stdio.h main() { int z; int *x;//ポインタ変数xを宣言 x = z;//アドレスを代入 *x = 10;//xに代入されているアドレスに10を代入 printf("xに代入されたアドレスは%p\n アドレスxの中の値は%d\nzの値は%d\n",x,*x,z); } 演習 2つのポインタ変数に,同じアドレスを代入して,一方のポインタ変数を使って値を代入したとき,他方のポインタ変数を使って中の値を見たとき,同じ値となることを確認するプログラムを書け.
https://w.atwiki.jp/fekai2/pages/34.html
ポインタ ここでいうポインタは、戦闘アニメを指定する(グラフィックやアニメや効果音等)ポインタの事。 アニメ移植or自作をするには是非とも知っておきたい。 スレ7章nTkMu418氏の解析がほとんどなので感謝しつつ読むように。あとはこまごまとした説明。 ▼戦闘アニメ指定ポインタ概要 1つのアニメは、識別子(12バイト)と5つのポインタ(4*5で計20バイト)で構成される。 識別子は、戦闘アニメポインタを見た時にそれがどの戦闘アニメのものであるかをわかりやすくするための文字列。 5つのポインタは、戦闘アニメのどのタイミングでどの画像を表示し、動かし、音を出し、HP減少やHITエフェクトを出すか、に関わる。 ▼識別子 StaringでRomを開いてアドレスC00000を見てみると。右側の方に「lorm_sp1」という文字列や似た物を確認できるはず。 これが識別子。「lorm_sp1」はLord-Men-Spearを略したもので「ロード男の戦闘アニメ」を意味する。 文字からクラスを推測できれば残りもわかるはず。FEditorで確認してもよい。 二つ目の「lorm_sp1」だが、こちらは「武器なし時のアニメ」である。 たいてい後ろの方にあるのが武器なしアニメの識別子なのだが文字列が同じであることがしょっちゅう。全く持って紛らわしry。 識別子があることで、パッと見でどのアニメか分かるという事と、文字列検索で飛んでこれるという利点がある。 ▼5つのポインタ 識別子の後、4バイト分のスペース00を挟んで** ** ** 08という形の物が5つ並ぶ。 これらがポインタ。一つ目のポインタから順に、「ポインタ1」「ポインタ2]・・・「ポインタ5」と呼ばれる。 各ポインタの概要は以下の通り。 ポインタ1:ポインタ2(解凍後)の各パートの開始アドレスを指定 ポインタ2:圧縮。85コマンド(効果呼び出し)と86コマンド(画像呼び出し:ポインタ3と連動)を指定。 ポインタ3:圧縮。ROM内のバラバラ画像を貼り合わせる。 ポインタ4:ポインタ3の敵側(逆向き)バージョン ポインタ5:圧縮パレットデータ 以下に、各ポインタの詳しい情報を掲載する。 ▼ポインタ1 未圧縮 ポインタ2(解凍後)の各パートの開始アドレスを指定 00 00 00 00 B0 01 00 00 60 03 00 00 A8 05 00 00 F0 07 00 00 00 08 00 00 10 08 00 00 54 08 00 00 98 08 00 00 AC 08 00 00 C0 08 00 00 D4 08 00 00 とあれば、 パート1:0x0000 パート2:0x01B0 パート3:0x0360 ~ パート12:0x08D4 …といった感じ ▼ポインタ2 要解凍 85コマンド(効果呼び出し)と86コマンド(画像呼び出し:ポインタ3と連動)で構成される。 12個のパートに分かれている。00 00 00 80で1パート終了。 パート1,2:通常攻撃アニメ。1と2は同じでもおk? パート3,4:クリティカル。3と4は同じでもおk? パート5:魔法攻撃。 パート6:魔法クリティカル。 パート7,8:回避アニメ。同じでもおk パート9,10,11:棒立ちアニメ。3つとも同じでおk パート12:攻撃よけられアニメ。パート1から、ヒットエフェクト、ヒットSEを抜けばおk ※85コマンド 4バイトで構成され、エフェクトや効果音、ダメージ処理などを行う。 ** 00 00 85:**で効果指定。 ※86コマンド 12バイトで構成され、ポインタ3で貼り合わせた1枚絵を呼び出す。GIFの1コマと思えばおk ①(05) 00 ②(0A) 86 ③(B8 40 E2 08) ④(30 03) 00 00 ①表示フレーム ②通し番号?とりあえず順番につけとけばおk ③画像の先頭アドレス。NLZ-GBAでぶっこんだ場所 ④ポインタ3(解凍後)の開始アドレスを指定 ▼ポインタ3 以下抜粋。長いので焦らず必要になった時に少しずつ読み進めるといい。 ・要解凍 ・ROM内のバラバラ画像を貼り合わせる。 ・12バイトで画像1かけら。 00 00 00 80 00 00 F0 FF E8 FF 00 00 00 80 00 40 04 00 10 00 E8 FF 00 00 00 40 00 40 80 00 F0 FF 08 00 00 00 00 00 00 00 84 00 10 00 08 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 これはロードヘクトル(斧)のポインタ3の先頭部分である。 まずは1行目 ①(00 00 00 80) ②(00) 00 ③(F0 FF) ④(E8 FF) 00 00 ★NLZ-GBAで表示される256×64の画像の、8×8を□として考え、下記のように番号を振る。まあずれるけど。 ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ ②★の番号より、切り出す始点を指定 ここでは、①(00 00 00 80) ②(00) なので ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ のように切り出す。 ③X座標④Y座標 切り出した画像を先頭画面のどこに配置するか指定。2バイト目が00なら正、FFなら負。 ただしXは右が正、Yは「下が」正。もちろん敵だと左右逆。 原点の位置は大体キャラの立ち位置あたりと思えばおk ここでは、③(F0 FF) ④(E8 FF)なので「原点から左に16ドット、上に24ドット」が指定位置。 ただし、切り出した画像は「左上を指定位置に合わせ、右下に展開」するので、実際には原点にかぶさるように 配置されるわけである。 ちなみにX座標を(C8 FF)ぐらいにすると、ちょうど敵の目の前あたりに配置される。 続きを配置していくと、 00 80 00 40 04 00 10 00 E8 FF 00 00 で ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 配置座標も、ちょうどさっきの切片と接するように指定されている。 00 40 00 40 80 00 F0 FF 08 00 00 00 で ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 00 00 00 00 84 00 10 00 08 00 00 00 で ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80□□□□■□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ 01 00 00 00 00 00 00 00 00 00 00 00 で貼り合わせ終了 以上により、貼り合わせで ― 0 1 2 3 4 5 6 7 8 9 A B C D E F 101112131415161718191A1B1C1D1E1F 00■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 20■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 40■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 60■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□ 80■■■■■□□□□□□□□□□□□□□□□□□□□□□□□□□□ A0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ C0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ E0□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□ この部分が原点付近に描画されたことになる。NLZ-GBAで0xE23084を覗いてみればわかるが、これはヘクトルの立 ち絵そのものである。 以上は、ポインタ3の先頭部分なので開始アドレスは0x0000である。 ▼補足 画像の貼り付け先は重なっていてもよい。 その場合は、最初に切り出し貼り付けた画像が前面に来る。 よってロードヘクトル(斧)のポインタ2内にある86コマンド、 01 00 00 86 84 30 E2 08 00 00 00 00 で、ヘクトルの立ち絵が呼び出されるわけである。 おっと、ポインタ3の①の説明が抜けてた ①切り出す形を指定するコマンド。 ・00 80 00 80 ■■ ■■ ■■ ■■ ・00 40 00 80 ■■■■ ■■■■ ・00 00 00 80 ■■■■ ■■■■ ■■■■ ■■■■ ・00 80 00 40 ■ ■ ■ ■ ・00 40 00 40 ■■■■ ・00 00 00 40 ■■ ■■ ・00 80 00 00 ■ ■ ・00 40 00 00 ■■ ・00 00 00 00 ■ } すいません訂正です。 ポインタ4はポインタ3と同じとか書いたが、すまんありゃウソだった。 ポインタ3は右側(味方側)表示用、 ポインタ4は左側(敵側)表示用みたいです。 つまりポインタ3と4を同じにすると、 左側に表示されたとき背中を向けた状態になります。 ポインタ4は構造こそポインタ3と同様ですが、 (00 00 00 80)→(00 00 00 90) (00 80 00 40)→(00 80 00 50) などのように、 780に列挙した①形指定コマンドの4バイト目に+10hしたものが使われています。 これは「切り出した画像を左右反転」しているようです。 画像が左右反転しても、「左上を指定位置に合わせ、右下に展開」することは 変わらないので③X座標も変化させる必要があります。 以上のような仕様なので、 ④Y座標や②切り出し始点はポインタ3と同じでよいことになります。 ▼ポインタ5 ユニットカラーを参照 名前 コメント
https://w.atwiki.jp/abwiki/pages/34.html
ポインタとはメモリアクセスの手段。 主に文字列操作、参照渡しもどき、関数呼び出しのオーバーヘッド削減、 関数テーブル、メモリの動的確保 などに使うのが一般的。 [[Dim]] pp As *Byte これでppはByte型データを指すポインタができる。 同じように Dim pp As *Long でLong型を指すポインタが宣言できる。 特性 ポインタはメモリアドレスを保持するのと、指した先の値を取り出すことができる。 Dim h[100] As Byte Dim ppp As *Byte ppp = h これでpppはhの先頭アドレスを指している。 ppp[0]とかppp[2]とか添字を付けることで、指した先ppp[0]ならh[0]の、ppp[2]ならh[2]の値を取り出すことができる。 また、ppp[2]=5とか、代入もできる。 参照渡しもどき ABではByVal,ByRefで値渡し、参照渡しを切り替えることができるが、ポインタを使って参照渡しもどきを使うことができる。 値渡しでは引数(この場合pのアドレス)は変わらないが指す先の値は変えることができる。 Sub sexy(p As *Byte) p[0] = 0 [[End]] Sub
https://w.atwiki.jp/cschola/pages/73.html
結構長いですが、C言語の中核をなす大事な部分です。 何度も繰り返し学習して、自分のものにしましょう。 第1項 ポインタ 今回はポインタについて説明します。ポインタとは「メモリ」上の「アドレス」を格納できる変数です。 「メモリ」とはPCの記憶領域です。 「アドレス」は「場所を示す」ものです。住所や郵便番号のようなものです。 「メールアドレス」といえばメールの行きつく「場所を示す」ものですね。 前回までのプログラムで変数を使ってきました。 変数を宣言するとその変数の型の大きさのに合わせた領域が「メモリ」上に確保されます。 「メモリ」上のどの場所が確保されるのかはわかりません。 使える場所をコンピュータが適当に選んで割り当てます。 「メモリ」上のどの場所に割り当てられたのか、それを示すのがアドレスです。 アドレスを見る 次のプログラムを書いて、実行する前に今まで書いてきたプログラムとの違いを探してみましょう。 int num = 10; printf("numの値は%dです。\n",num); printf("numのアドレスは%pです。\n", num); 実行してみると上一行には今までと同じように num の値が表示され、 下の一行には数字とアルファベットが表示されています。 これは16進数で示されるアドレスです。 メモリ上のどの場所にデータが格納されているのか示します。 変数は必ずアドレスを持っていて、変数名の前に を付けることでその変数のアドレスを得ることができます。 double型 や char型の変数もアドレスを持っています。 練習問題 次のようなプログラムを作ってください。 第1問 double型の変数を宣言して、そのアドレスを表示する。 第2問 char型の変数を宣言して、そのアドレスを表示する。 第二項 アドレスを格納する変数 前項で画面に表示したアドレスは変数に格納することができます。 アドレスを格納する変数をポインターといいます。 ポインターは次のように宣言します。 int num = 0; //int型変数numの宣言 int* p = num; //int型ポインターの p を宣言 今回は int型の num のアドレスを格納しています。 ポインターは 格納したい変数の型に * を付けて宣言します。 * の位置は int* p でも int *p でも宣言できます。 double型 の変数のアドレスを格納したい場合は double* と書きます。 char型も同様です。 ポインターに変数のアドレスを格納すると、ポインターからその変数にアクセスできるようになります。 ポインターの名前に * を付けることでアクセスできます。 int num = 0; int* p = num; printf("numの値は%d\n",num); *p = 10; //pからnumにアクセスしてnumの値を変更 printf("numの値は%d\n",num); //numの値を表示 printf("numの値は%d\n",*p); //pからnumにアクセスして numの値を表示 printf("numのアドレスは%p\n",p); この使い方は double型 や char型でも同じです。 ポインターは、 int* p = num; のように宣言と同時に初期化しましょう。 初期化していないポインターはどこのアドレスを指しているかわからず、危険なふるまいをする可能性があります。 練習問題 次のようなプログラムを作ってください。 第1問 double型の変数を宣言し、そのアドレスをポインターに格納して、 ポインターから変数にアクセスして数値を代入し表示する。 第2問 char型の変数を宣言し、そのアドレスをポインターに格納して、 ポインターから変数にアクセスして文字を代入し、ポインターから参照して表示する。
https://w.atwiki.jp/chugoku/pages/106.html
関数を指すポインタ int abc(int);の関数を指すポインタは、int (*p)(int);と宣言できる。p変数はその関数の形式(戻り値、引数の数と型)が一致すればその関数のアドレスを入れることができる。 b.c--------------------------------------------------------------- #include stdio.h int abc(int x){ return x+1; } int main(void) { int (*p)(int); p=abc; printf("%d\n",p(1)); return 0; } コンパイルは、gcc b.cやcl b.c コマンドプロンプト b.exe 2 Javaや最近はやりのRubyなどは 実行するまでどの関数を処理するかわからない。 実行時に関数を選択するにはこうした関数のアドレスを配列(表)する。関数テーブルを作ることでアセンブリ言語でいうジャンプテーブル(割り込み用の関数テーブルなど)を作ることができる。 ポインタを指すポインタ int k,*p; p= k; ポインタpを指すポインタppは、int **p=p; a.c---------------------------------------------------------- #include stdio.h #include string.h main(void){ int k,*p; int **pp; k=5; p= k; pp= p; printf("%d\n",k); printf("%d\n",*p); printf("%d\n",**pp); ++**pp; printf("%d\n",**pp); } コンパイルは、gcc a.cとかcl a.c コマンドプロンプト> a.exe 5 5 5 6 ポインタを指すポインタに対してさらにこれを指すポインタは***jとなるが実際にはつかわない。 「今日の訪問数 - 」 「昨日の訪問数 - 」 「今までの訪問数 - 」 名前 コメント
https://w.atwiki.jp/gamexprogram/pages/41.html
C言語 ポインタ1 C言語で最大の難関と言われるポインタです。 使用方法 [[データ型]] *変数名; 変数前に*(アスタリスク)をつけることでポインタを指します。 例文 //================================================ //include //================================================ #include stdio.h //================================================ //メイン関数 //================================================ int main(void) { int a = 1; int *p; p = a;//ポインタにアドレスを入れる [[printf]]("aの変数のアドレスは%p\n", a); printf("aの変数内の数値は%d\n", a); printf("pの変数のアドレスは%p\n", p); printf("pの変数内の数値は%d", *p); return 0; } 実行結果 解説 int *p; pという名前のポインタを宣言しています。 p = a; ポインタのアドレスを代入しています。 printf("aの変数のアドレスは%p\n", a); %pはアドレスを表示させるものです。 そして、アドレスを示すので変数の前に をつけています。 printf("pの変数のアドレスは%p\n", p); printf("pの変数内の数値は%d", *p); ポインタにアドレスを入れた場合は、数値とアドレスを 見る方法が変わります。 アドレスの場合は、前に何も付けずに、 数値の場合は、*を付けています。 ややこしいので、少し表にしてみました。 普通の変数の場合 数値 何も付けない アドレス 前に ポインタの場合 数値 前に* アドレス 何も付けない C言語に戻る
https://w.atwiki.jp/newclang/pages/21.html
11 :デフォルトの名無しさん:2010/04/13(火) 02 18 03 別に僕は今のC言語で問題ないんだけど 新しいのを作るとしたらポインタ、特に関数へのポインタを引数に取り、関数へのポインタを引数に取る関数へのポインタを返す関数へのポインタとかを美しく記述できる文法を切口にポインタに変わるアドレッシング方法を考えればいいとおもう int - p; int ()(void) - fp; int ()(int ()(void) -) - ()(int - ()(void) -) - fpp; ダメだ、読みにくい int (*(*fpp)(int (*)(void)))(int (*)(void)); そもそも関数ポインタに代わるなにか、高階関数とかあればよいのだろうか 12 :デフォルトの名無しさん:2010/04/13(火) 02 25 49 11 普通に関数ポインタをtypedefすれば良いんじゃない? 13 :デフォルトの名無しさん:2010/04/13(火) 02 26 51 11 そのための typedef。 14 :12:2010/04/13(火) 02 27 09 まぁ、関数ポインタを見やすくすること自体は良いと思うけど… 15 :デフォルトの名無しさん:2010/04/13(火) 02 44 25 ちょっとした思い付きなんだけどスコープ内にある関数なら、 第一引数と一致する型の変数から暗黙的に関数を呼べると以外と便利かも… ※javascriptのthisポイントみたいな感じで char *copy( char *src, *dst ); char *trim( char *src ); char *toupper( char *src ); p- copy(*dst)- trim()- toupper(); 16 :15:2010/04/13(火) 02 45 59 アホだ俺、もう寝よう…orz p- copy(*dst)- trim()- toupper(); × p- copy(dst)- trim()- toupper(); ○ 関数ポインタならDのfunctionやScalaの関数宣言が参考になると int function(int) fp; // fp は関数へのポインタ int delegate(int) dg; // dg は関数へのデリゲート val f (a Int,b Int)= Int = {(a Int,b Int)= a+b} がデリゲード val f (a Int,b Int)- Int が関数ポインタとか 15 C#の拡張メソッドね。 乱用すんなとは言われてるけど、なかなか便利。 関数リテラル、関数内関数ぐらいは問題なさげ クロージャは、無限エクステントなしでよければ問題なさげ それでもforeachみたいなのに渡す分には困らない 値として返せないけど