約 3,897,408 件
https://w.atwiki.jp/cschola/pages/30.html
thisポインタ オブジェクトのポインタ
https://w.atwiki.jp/bokuyo/pages/85.html
ポインタ総復習。 この記事は左に寄り過ぎています。 真ん中はこの辺 ↓ もうだめかもしんない。ポインタ使ってるとわけわからん。 #include iostream int main() { int eureka = 7; int* renton = eureka; //指してるアドレスを表示 std cout renton std endl; //指してる場所が持つ値を表示 std cout *renton std endl; //自分自身のアドレスを表示 std cout renton std endl; //int*型のポインタも定義できる int** unco = renton; //int**型のポインタも定義できる int*** pants = unco; return 0; } ポインタはこう考えてはいかがです? これはあくまでもぼくが思う考え方であって、C++の定義や仕様とは逸脱している可能性がありますのよ。 ポインタは特別なものではないの。 int型やfloat型、ほかにもstring型やvector型があるように、ポインタも型のひとつなの。 つまり、「int型のポインタ」ではなくて「int*型("int型のポインタ"型)」というような感じ。 じゃあ、int型は整数を、float型は浮動小数点を要素にしますけども、「int*型」は何をもつの? それはね、「int型のアドレス」をもつの。あとは他の型と使い方は同じよ。なーにただそれだけよ。 どう?ポインタってそんなにむつかしくないでしょ? そんな経緯で、「int *unco;」ではなくて、「int* unco;」と書く方が好きなのです。 コメント 修正したほうがいい箇所や疑問点、気になったことなどを気軽に書く欄(あまりにも長期戦となるような議論的なコメントは他の媒体でやる方針で) あと、ページが重くなるのと見づらくなりそうなのを防ぐためコメントは定期的に削除してwikiに改めてまとめます。 たとえて言うなら、コメントだけでページの半分を埋め尽くされたwikipediaを見たくない心理に近い。 名前 コメント
https://w.atwiki.jp/we_hate_sunshine/pages/71.html
テクスチャマッピングをやっていて、ポインタについておさらいする羽目になりました。 テクスチャに用いる画像データはテクスチャバッファに格納します。 テクスチャバッファはピクセル単位で縦と横の二次元配列で表現しています。 そして、1画素(ピクセル)がR,G,B,αの4Byteデータで表されるので、テクスチャバッファは unsigned char texBuf1[横の画素数][縦の画素数][4]; で定義します。 ※テクスチャバッファは横と縦の比が同じでかつ2のべき乗になっていなければなりません。 配列を使う場合は宣言時に配列サイズを決めておかなければならないのはC言語のルールです。 しかし、サイズを予め決めておくとアプリケーションとして自由度が低下する恐れがあります。 なので、そのような場合、 実行中にサイズを計算して必要な配列のメモリを随時確保(メモリの動的確保)する手が考えられます。 しかし相手は多次元配列(三次元配列)です。これを動的に確保しようとするとかなりややこしくなります。 配列へのポインタ そしてその配列へのポインタを要素に持つ配列へのポインタ さらにその配列ポインタをを要素に持つ配列へのポインタ で表現します。 unsigned char*** texBuf2; // 三次元配列を表す。 //メモリ確保の仕方 texBuf2 = (unsigned char***)malloc(横の画素数); for(i = 0; i 横の画素数; i++) { texBuf2[i] = (unsigned char**)malloc(縦の画素数); for(j = 0; j maxY; j++) { texBuf2[i][j] = (unsigned char*)malloc(4); } } こうやってメモリを確保することで、 texBuf1もtexBuf2も同様にtexBuf○[10][10][2]というように要素にアクセスすることができます。 しかーし、両者は同様に要素の参照が可能で、見かけは似ていますがコンパイラは両者を完全に区別しています。 前者は確かにそのまま多次元配列と呼ばれるのですが、後者はディスプレイと呼ばれるらしいです。 同違うのかっ。これが難しいんです。 詳しい説明は長くなるので、一番顕著な違いを(理由もなしに)言うと、 1次元配列で表せるか否かです。 texBuf1は1次元配列で表せれますがtextBuf2は表せれません。 この違いの影響がもろに出るのは関数の引数です。 OpenGLでテクスチャを当てはめる関数はglTexImage2D()という関数で、引数にテクスチャバッファを指定します。 どんな型で受け取るかというとGLVoid*型で受け取ります。 要は配列へのポインタを受け取りますという意味なんですが、 これだけでは中でどのように要素にアクセスしているのかわかりません。 けど一つ言えることは、どのように要素にアクセスしてもいいような配列のポインタを渡せということです。 (配列は色々アクセスの仕方があるのです) で、つまりのところtextBuf2はアクセスの仕方によって正しい要素の値を取得できないので、 引数に与えることはナンセンスです。 先にも言ったように1次元配列で表せれないからってことに関わってくるんですが、 それはなぜかというと、参照の仕方が違うからです。 例えば[]による参照ではなく、ポインタで参照していくと、 texBuf1の場合、*(texBuf1++)するごとにR→G→B→α→Rと連続して値を取得していけます。 しかし、texBuf2の場合、横成分、縦成分、RGBA成分を表す配列がばらばらにメモリ空間に存在します。 つまり、*(texBuf2++)をして取得できるのは横の一列のRの値だけです。 うーん、難しいです。要はC言語で多次元配列の動的確保は極力避けるべきだということです。 なのでどーするかというと、 unsigned char* texBuf3 = (unsigned char*)malloc(横の画素数 * 縦の画素数 * 4); というように1次元配列で確保する必要があったわけです、はい。 とまぁ、改めてポインタの奥深さを知った一日でした。 「ディスプレイ」って言葉ははじめて聞きました。なるほど。 -- ぷん (2007-04-02 02 54 52) ぷんこなら常識、ぜたいはまんねー、とオモタ -- NZ-000 (2007-04-02 12 34 05) へーOpenGLなんてやってんのね。winじゃもうDirectXしか聞かないけど。 -- qutto (2007-04-05 00 32 34) キャストの型が合ってなくない? -- qutto (2007-04-05 00 32 44) まじ? -- NZ-000 (2007-04-05 00 48 56) 修正した。 -- NZ-000 (2007-04-07 03 04 46) 名前 コメント
https://w.atwiki.jp/sevenlives/pages/186.html
マウスポインタ【カーソル】 読み:まうすぽいんた 英語:mouse pointer, mouse cursor 意味: マウスで操作する画面上?の矢印。 それを目的の場所へ持って行きクリックすることで画面上の操作をする。 2007年02月12日
https://w.atwiki.jp/isoroku_be/pages/67.html
情報 作者名:しらたま 引用元:なでしこプログラム掲示板「代用関数ポインタ」 概要 なでしこで関数ポインタを扱えるようにする。 本体 ●VirtualAlloc({参照渡し}lpAddress,dwSize,flAllocationType,flProtect)=DLL("kernel32.dll", "LPVOID VirtualAlloc( LPVOID lpAddress, int dwSize, DWORD flAllocationType, DWORD flProtect )") ●VirtualFree({参照渡し}lpAddress,dwSize,dwFreeType)=DLL("kernel32.dll", "BOOL VirtualFree( LPVOID lpAddress, int dwSize, DWORD dwFreeType )") ●MoveMemory({参照渡し}d,{参照渡し}s,l)=DLL("kernel32.dll", "VOID RtlMoveMemory( LPVOID Destination, LPVOID Source, int Length )") ●GetProcAddress(hModule,{参照渡し}lpProcName)=DLL("kernel32.dll", "DWORD GetProcAddress( HMODULE hModule, // DLL モジュールのハンドル LPCSTR lpProcName // 関数名 )") ●GetModuleHandle({参照渡し}ModuleName) =DLL("kernel32.dll", "HMODULE GetModuleHandleA( LPCTSTR ModuleName )") !MEM_COMMIT=$1000 !MEM_RELEASE=$8000 !PAGE_EXECUTE_READWRITE=$40 !変数宣言が必要 それ待避用スタックとは配列 ●それプッシュ それ待避用スタックにそれを配列追加 ●それポップ Aとは整数 Aはそれ待避用スタックの配列要素数 それはそれ待避用スタック[A-1] それ待避用スタックのA-1を配列削除 ●AddBinary({参照渡し}target,value,size) MoveMemory(target,POINTER(value),size) target=target+size !関数ポインタ既定イベント名=「前処理」 !nako_group_execポインタ=GetProcAddress(GetModuleHandle(「dnako.dll」),「nako_group_exec」) ■関数ポインタ ・{イベント}イベント ・{整数}ダミー関数 ・{非公開}前処理~ F引数数 回 引数[回数-1]=0 MoveMemory(POINTER(引数[回数-1]),スタックアドレス+4+4*回数,4) 自身→イベント ・{配列}引数 ・{非公開 整数}スタックアドレス ・{整数}返り値 ・{非公開}F引数数 ・引数数←引数数設定→引数数取得 ・{非公開}引数数設定(V)~ それプッシュ pcとは整数 もしダミー関数=0ならば ダミー関数はVirtualAlloc(0,64,MEM_COMMIT,PAGE_EXECUTE_READWRITE) pc=ダミー関数 AddBinary(pc,$55,1) //push ebp AddBinary(pc,$EC8B,2) //mov ebp,esp pc-ダミー関数という AddBinary(pc,$BA,1) pc-ダミー関数という AddBinary(pc,POINTER(スタックアドレス),4) //mov edx,POINTER(スタックアドレス) AddBinary(pc,$2A89,2) //mov dword ptr [edx],ebp AddBinary(pc,$68,1) AddBinary(pc,POINTER(関数ポインタ既定イベント名),4) //push char* AddBinary(pc,$68,1) AddBinary(pc,ADDR(自身),4) //push PHiValue AddBinary(pc,$B8,1) AddBinary(pc,nako_group_execポインタ,4)//mov eax,nako_group_execポインタ AddBinary(pc,$D0FF,2) //call eax AddBinary(pc,$058B,2) AddBinary(pc,POINTER(返り値),4) //mov eax,POINTER(返り値) AddBinary(pc,$5D,1) //pop edp AddBinary(pc,$C2,1) AddBinary(pc,V*4,2) //ret 8 #AddBinary(pc,$00,1) F引数数はV それポップ ・{非公開}引数数取得~ それはF引数数 ・作る~ スタックアドレスは0 返り値は0 ダミー関数=0 F引数数は-1 ・解放~ VirtualFree(ダミー関数,0,MEM_RELEASE) //サンプルプログラム #実行テスト1(GDIオブジェクト(ペン)列挙) ●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()") ●GetDC(hwnd)=DLL("user32.dll", "HDC GetDC( HWND hwnd )") ●ReleaseDC(w,d)=DLL("user32.dll", "int ReleaseDC( HWND hWnd, HDC hDC )") ●EnumObjects(hdc,nObjectType,lpObjectFunc,lParam)=DLL("gdi32.dll", "int EnumObjects( HDC hdc, int nObjectType, int lpObjectFunc, int lParam )") !OBJ_PEN=1 ログとはメモ そのレイアウトは「全体」 hdesktopとは整数 hdcとは整数 テストとは関数ポインタ その引数数は2 そのイベントは~ バッファとは文字列 バッファに16を確保 表示バッファとは文字列 MoveMemory(バッファ,INT(自身→引数[0]),16) バッファの1を「int」でバイナリ取得 それで条件分岐 0ならば、それは「実線」 1ならば、それは「破線」 2ならば、それは「点線」 3ならば、それは「一点鎖線」 4ならば、それは「二点鎖線」 5ならば、それは「非表示」 6ならば、それは「塗りつぶし」 表示バッファは「ペンタイプ:」&それ&改行 バッファの5を「int」でバイナリ取得 表示バッファは表示バッファ&「X:」&それ バッファの9を「int」でバイナリ取得 表示バッファは表示バッファ&「 Y:」&それ&改行 バッファの13を「int」でバイナリ取得 表示バッファは表示バッファ&「RGB:」&HEX(それ)&改行 ログのテキストはログのテキスト&表示バッファ 自身→返り値は10 hdesktop=GetDesktopWindow() hdc=GetDC(hdesktop) EnumObjects(hdc,OBJ_PEN,テストのダミー関数,100) いう ReleaseDC(hdesktop,hdc)#*/ #実行テスト2(子ウィンドウ列挙) ●EnumChildWindows(hWndParent,lpEnumFunc,lParam) =DLL("user32.dll", "BOOL EnumChildWindows( HWND hWndParent, LPWNDENUMPROC lpEnumFunc, LPARAM lParam )") ●GetWindowText(hWnd,{参照渡し}lpString,nMaxCount) =DLL("user32.dll", "int GetWindowTextA( HWND hWnd, LPTSTR lpString, int nMaxCount )") ●GetDesktopWindow()=DLL("user32.dll","HWND GetDesktopWindow()") ログとはメモ そのレイアウトは「全体」 テストとは関数ポインタ その引数数は2 そのイベントは~ バッファとは文字列 表示バッファとは文字列 バッファに128を確保 GetWindowText(自身→引数[0],バッファ,127) バッファのそれ バイト左部分 表示バッファは自身→引数[0]&「,」&それ&改行 ログのテキストはログのテキスト&表示バッファ 自身→返り値は1 EnumChildWindows(GetDesktopWindow(),テストのダミー関数,0) 名前 コメント
https://w.atwiki.jp/isoroku_be/pages/189.html
情報 作者名:YouTubeダウンロードし放題 引用元:なでしこプログラム掲示板「代用関数ポインタ」なでしこライブラリ「関数ポインタ」 概要 関数ポインタが最新のなでしこで使えない..って人が多かったので不具合を直しました。 これを使えばなでしこで マルチスレッド フォームをWinAPIレベルから作成してメッセージループを回す 非同期な通信 重い処理の非同期実行 などの高度な処理を実現できます ソースダウンロード サンプル集ダウンロード 変更点 ver2.10 ●関数ポインタ作成 でイベントを事前にEVALで登録するように修正(高速化) ver2.05 使いやすいように関数命令を追加●関数ポインタ取得●関数ポインタ取得●関数ポインタ実行 2個以上関数ポインタを作成した場合のアドレス重複エラーを修正 関数内での宣言をサポート わざわざVirtualAllocでメモリを確保する理由もなく、メモリを解放し忘れる人が多いのでなでしこの「確保」命令に置換(追記 やっぱり実行アクセスの有無が違うらしい... でも実行アクセスがなくてもなぜか実行できるので保留。) ver1.01 グローバルからアクセスできるように 引数の型を指定できるように 本体 !変数宣言は必要 !NAKO_GROUP_EXEC=GetProcAddress(GetModuleHandle("dnako.dll"),"nako_group_exec"); !関数ポインタ既定イベント名 = "前処理"; ■関数ポインタ ・{イベント}イベント ・{整数}ポインタ ・{配列}引数 ・{配列}引数型 ・ポケット ・タグ ・{非公開}初期化({グループ}参照)~ 型サイズ=空 引数型で反復 対象の型サイズ取得を型サイズに配列追加 バッファに64を確保 バッファの01に$55を「BYTE」でバイナリ設定 バッファの02に$EC8Bを「SHORT」でバイナリ設定 バッファの04に$BAを「BYTE」でバイナリ設定 バッファの05にPOINTER(スタック)を「int」でバイナリ設定 バッファの09に$2A89を「SHORT」でバイナリ設定 バッファの11に$68を「BYTE」でバイナリ設定 バッファの12にPOINTER(関数ポインタ既定イベント名)を「int」でバイナリ設定 バッファの16に$68を「BYTE」でバイナリ設定 バッファの17にADDR(参照)を「int」でバイナリ設定 バッファの21に$B8を「BYTE」でバイナリ設定 バッファの22にNAKO_GROUP_EXECを「int」でバイナリ設定 バッファの26に$D0FFを「SHORT」でバイナリ設定 バッファの28に$058Bを「SHORT」でバイナリ設定 バッファの30にPOINTER(返り値)を「int」でバイナリ設定 バッファの34に$5Dを「BYTE」でバイナリ設定 バッファの35に$C2を「BYTE」でバイナリ設定 バッファの36に(型サイズの配列合計)を「SHORT」でバイナリ設定 ポインタ=POINTER(バッファ) ・{非公開}前処理~ TMPとは整数 TMP=スタック+4 (引数型の配列要素数)回 引数[回数-1]=0 TMP=TMP+型サイズ[回数-1] MoveMemory(POINTER(引数[回数-1]),TMP,型サイズ[回数-1]) 返り値=イベント ・{文字列}バッファ ・{整数}スタック ・{配列}型サイズ ・{整数}返り値 ●型サイズ取得(型の) 型=型を大文字変換 型で条件分岐 「CHAR」ならば、(8/8)で戻る 「BYTE」ならば、(8/8)で戻る 「WCHAR」ならば、(16/8)で戻る 「SHORT」ならば、(16/8)で戻る 「WORD」ならば、(16/8)で戻る 「INT」ならば、(32/8)で戻る 「UINT」ならば、(32/8)で戻る 「LONG」ならば、(32/8)で戻る 「DWORD」ならば、(32/8)で戻る 「ULONG」ならば、(32/8)で戻る 「LONG_PTR」ならば、(32/8)で戻る 「DWORD_PTR」ならば、(32/8)で戻る 「HWND」ならば、(32/8)で戻る 「LPARAM」ならば、(32/8)で戻る 「WPARAM」ならば、(32/8)で戻る 「COLORREF」ならば、(32/8)で戻る 「PTSTR」ならば、(32/8)で戻る 「PCTSTR」ならば、(32/8)で戻る 「LPTSTR」ならば、(32/8)で戻る 「LPCTSTR」ならば、(32/8)で戻る 「LPVOID」ならば、(32/8)で戻る 「BOOL」ならば、(32/8)で戻る もし、LEFTB(型,2)=「LP」ならば、4で戻る もし、LEFTB(型,1)=「P」ならば、4で戻る もし、LEFTB(型,1)=「H」ならば、4で戻る 「{型} 型は定義されていません」とエラー発生 ●関数ポインタ作成(型として) 結果とは変数 結果を関数ポインタとして作成 結果→引数型=型を","で区切る 結果で戻る 関数ポインタ取得用変数とは変数 ●関数ポインタ取得(関数名から引数型で) 関数ポインタ取得用変数=引数型として関数ポインタ作成 関数ポインタ取得用変数→初期化(関数ポインタ取得用変数) 実行文とは文字列="関数ポインタ取得用変数→ポケットは~グローバル {関数名}(" Iとは整数 Iで0から(引数型を","で区切るの配列要素数-1)まで繰り返す もし、回数 1ならば、実行文に","を追加 実行文に"自身→引数[{I}]"を追加 実行文に")で戻る"を追加 EVAL(実行文) 関数ポインタ取得用変数→イベントは~自身→ポケットで戻る 関数ポインタ取得用変数→ポインタで戻る ●関数ポインタ実行(ポインタ,{配列}引数一覧,引数型,戻値型) 引数型=引数型を「,」で区切る 引数サイズとは配列 引数とは文字列 位置とは整数=1 引数型で反復 引数サイズ[回数-1]=対象の型サイズ取得 引数に(引数サイズの配列合計)を確保 引数一覧で反復 引数の位置にINT(対象)を引数型[回数-1]でバイナリ設定 位置に引数サイズ[回数-1]を直接足す EXEC_PTR(ポインタ,引数のバイト数,引数,戻値型)で戻る ●GetProcAddress(hModule,lpProcName) =DLL("kernel32.dll", "DWORD GetProcAddress( HMODULE hModule, // DLL モジュールのハンドル LPCSTR lpProcName // 関数名 )") ●GetModuleHandle(lpModuleName) =DLL("kernel32.dll", "HMODULE GetModuleHandleA( LPCTSTR lpModuleName // モジュール名 )") ●MoveMemory(Destination,Source,Length) =DLL("kernel32.dll", "VOID RtlMoveMemory ( PVOID Destination, // 移動先 VOID *Source, // 移動したいブロック SIZE_T Length // 移動したいブロックのサイズ )") !変数宣言は不要 例1 マルチスレッド ポインタ=「MyThreadProc」から「LPRAM」で関数ポインタ取得 スレッド識別子とは整数 CreateThread(0,0,ポインタ,回数,0,POINTER(スレッド識別子)) 「ユーザーを待機している最中に...」という ●MyThreadProc(lpParameter) 100回 母艦=「他の処理を実行することができます - 今の時間 {今}」 1秒待つ ●CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,dwCreationFlags,lpThreadId) =DLL("kernel32.dll", "HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // セキュリティ記述子 DWORD dwStackSize, // 初期のスタックサイズ LPTHREAD_START_ROUTINE lpStartAddress, // スレッドの機能 LPVOID lpParameter, // スレッドの引数 DWORD dwCreationFlags, // 作成オプション LPDWORD lpThreadId // スレッド識別子 )") 例2 窓列挙 ログとはメモ そのレイアウトは「全体」 ポインタ="MyEnumWindowsProc"から"HWND,LPARAM"で関数ポインタ取得 EnumWindows(ポインタ,0) ●MyEnumWindowsProc(hwnd,lParam) バッファとは文字列 バッファに260を確保 GetWindowText(hwnd,POINTER(バッファ),260) タイトルとは文字列=LEFTB(バッファ,それ) ログのテキスト=ログのテキスト "{hwnd},{タイトル}{~}" 1で戻る ●EnumWindows(lpEnumFunc,lParam) =DLL("user32.dll", "BOOL EnumWindows( WNDENUMPROC *lpEnumFunc, // コールバック関数 LPARAM lParam // アプリケーション定義の値 )") ●GetWindowText(hWnd,lpString,nMaxCount) =DLL("user32.dll", "int GetWindowTextA( HWND hWnd, // ウィンドウまたはコントロールのハンドル LPTSTR lpString, // テキストバッファ int nMaxCount // コピーする最大文字数 )") 総合 - 今日 - 人 昨日 - 人 名前 コメント
https://w.atwiki.jp/wiki4_mo/pages/13.html
ポインタについて int ans,*ansp; ここでのアスタリスクはanspをint*の型で宣言している。 ans=1; ansp= ans; anspにansのアドレスを代入 printf("%x",ansp); anspに入っている値(ansのアドレス)を表示 printf("%d",*ansp); anspに入っている値(ansのアドレス)の示す値を表示 こうるすと おなじこと int ans,ansp; ans=1; ansp=(int) ans; printf("%x"(int*)ansp);
https://w.atwiki.jp/catnap222/pages/472.html
ポインタの入れ替え 敵がいない部屋に敵を置きたい時などにお手軽なのが ポインタの入れ替えです。 SMILEでEdit→Pointersを押すと、こんなウインドウが出てきます。 ここに書かれている各種情報のありかを示すアドレスを、他の部屋と入れ替えてしまいます。 共通化もできますが、片方の部屋で情報をいじるともう片方も当然同じように変わってしまうので 注意が必要です。 共通化しても問題がないものは FX2 BG_Data Layer1_2 この3つです。これらの情報はSMILEでの編集ができない もしくは、編集する機会がほとんどないからです。 実際オリジナルでも多くの部屋で共通化されています。 セーブ時の注意 目的のアドレスを入れ替えてSave Pointersを押すと こんなダイアログが出てきます。 ここでは基本的に「いいえ」を選択します。 「はい」を押してしまうと元の読み込み先の情報が、入れ替えたアドレス先へ 上書きされてしまいます。 そうなると入れ替えた意味がなくなってしまう上に、入れ替えとは関係のない部屋の 情報を壊してしまうおそれもあるので、注意が必要です。 沢山のドキュメントありがとうございます、byteさん。 -- catnap222 (2009-07-12 11 08 22) 名前 コメント
https://w.atwiki.jp/yu2ww88/pages/19.html
プログラム起動時に入力された複数個のプログラム仮引数の文字数( \0 除く)を数え、例のように文字列と共に表示するプログラムを作成せよ。 なお、プログラムは次の2つの関数を含めること。 1. 文字数を数える関数 1つの文字列へのポインタを受け取り、文字数を返す。 2. 文字列を表示する関数 1つの文字列へのポインタを受け取り、これを表示する。 ★表示例 n = 5 tokyo n = 9 shinbashi n = 9 shinagawa n = 8 kawasaki n = 8 yokohama ★解答 #include stdio.h int cal_char(char *); void char_print(char *,int); int main(int argc,char **argv) { int n; for(argv++;*argv != NULL; argv++){ n = cal_char(*argv); char_print(*argv,n); } } int cal_char(char *pa) { int i; for(i=0;*pa != \0 ; i++,pa++); //文字列の最後にはナル「\0」が入るのでこれは数えない return i; } void char_print(char* pa,int n) { printf("n = %2d %s\n",n,pa); } "**argv //+1しておいて、次がNULLじゃないか確認。" ↓ "*argv //argvが空っぽだとNULLを返す。" ↓ "argv //実際にchar配列が入っている。文字列の最後には\0が存在。"
https://w.atwiki.jp/cschola/pages/74.html
第四項 ポインターを使った関数 ポインターは関数の中で使うことで真価を発揮します。 関数の中で使う前にポインターの使い方について復習しておきます。 int* p; //int型ポインターpを宣言。 int num = 0; //int型の変数numを宣言。 p = num; //pにnumのアドレスを格納 *p = 5; //pからアクセスしてnumの値を変更 int a = *p; //pからアクセスしてnumを参照 * と の使い方を覚えてください。 ポインターから変数へアクセスすることで値を変更したり、参照したりできることを覚えてください。 今まで scanf_s関数に変数を渡すときは変数の前に を付けていました。 これは変数のアドレスを渡していたのです。 変数のアドレスを渡すことができれば、scanf_s関数は数値を代入することができます。 変数名の前に を付ける以外にもう一つアドレスを渡す方法があります。 ポインターを宣言し、変数のアドレスを格納して、ポインターを引き数として渡す方法です。 int num = 0; int* p = num; printf("数値を入力してください\n"); scanf_s("%d",p); printf("入力された数値は%dです。\n",num); 整数型の引数を二つ受け取り、それぞれの値を入れ替える Swap関数を作ります。 void Swap(int* x,int* y){ int tmp = *x; *x = *y; *y = tmp; } /*~~~~~~~~~~中略~~~~~~~~~~*/ int a = 20; int b = 10; printf("aは%dです。\n",a); printf("bは%dです。\n",b); Swap( a, b); printf("aとbを入れ替えます。\n"); printf("aは%dです。\n",a); printf("bは%dです。\n",b); 関数の引数に a b と書くことで、変数のアドレスを関数にわたします。 アドレスを受け取るにはポインターが必要です。 この関数では x,y のポインターでアドレスを受け止めています。 アドレスを受け止めた x,y から本体にアクセスします。 本体にアクセスすることで、変数本体の数値を参照、変更できます。 練習問題 次のようなプログラムを作ってください。 第1問 int型変数のアドレスを受け取り、その変数に10を代入する関数を作る。 第2問 int型の変数 flag のアドレスを受け取り、flagの値が0なら1に1なら0にする関数を作る。 第五項 ポインターのポインター ポインターも変数の一種なので、自身もアドレスを持っています。 そのアドレスをほかのポインターに格納することもできます。 int num = 10; int* p = num; int** pp = p; //ポインターのアドレスを格納するポインター(ポインターのポインター) printf("%d\n",**pp); あまり使うことはないですが、ポインターのポインターのポインターも作ることができます。 int num = 5; int* p = num; int** pp = p; int*** ppp = pp; printf("%d\n",***ppp); ポインタの答え