• ベストアンサー

ポインタについてです

ポインタのアドレスを調べる実験をしました。 ファイル名はbenkyou.c int main(int argc, char *argv[]) { ・・・・ } コンパイルしてbenkyou.exeとし、MS-DOSコマンドプロンプトで benkyou zyxwv とコマンド。 その結果、主な各変数自身のアドレスが、 argv = 00430EA0 (この中には430EACが格納されている (以下、全てのアドレスの先頭2桁00を省略します *argv = argv[0] = 430EAC (この中には000062が格納されている *(argv+1) = argv[1] = 430EAB (この中には000062が格納 **argv = 000062 *(argv[0]+0)=000062 (この中には'b'が格納されている *(argv[0]+1)=000065 (この中には'e'が格納されている *(argv[0]+2)=00006E (この中には'n'が格納されている *(argv[1]+0)=00002A (この中には'z'が格納されている *(argv[1]+1)=000079 (この中には'y'が格納されている *(argv[1]+2)=00007A (この中には'x'が格納されている という結果になりました。 ここで不思議に思っているのは、*(argv[1]+0)、*(argv[1]+1)、・・・ 等のアドレス値の差がバラバラなことです。 自分が読んだ書籍などでは、この値は等間隔だと書いてあったような・・。char なら1バイトだから、おなじ配列ならばアドレス値は1ずつ増えると習った気がします。 バラバラにもなりうるのですか? 私の勘違いかもしれません。 混乱気味なので分かりやすく説明していただきたいです。 今回使ったコンパイラは Visual C++ です。

  • rousei
  • お礼率56% (111/196)

質問者が選んだベストアンサー

  • ベストアンサー
  • kary
  • ベストアンサー率55% (10/18)
回答No.1

62(b)や65(e)ですが、これはasciiコードを表していて、つまりアドレスに格納されている文字そのものを指しているのではないでしょうか。ただ、zは0x7A、xは0x78だと思うのでちょっと違うのかもしれません。お手元にコード表があれば確認してください。また、アドレスを表すなら、argv[0]+1等で*は必要ないのではないでしょうか。間違っていたらごめんなさい。

rousei
質問者

お礼

おっしゃる通りでしたm(_ _)m 恥ずかしい・・ またよろしくお願いします。

その他の回答 (1)

  • gatyan
  • ベストアンサー率41% (160/385)
回答No.2

#include <stdio.h> void main(int argc,char *argv[]) { printf("0番目 引数 %s\n",argv[0]); printf("0番目 引数1文字目のアドレス %p\n",argv[0]+0); printf("0番目 引数2文字目のアドレス %p\n",argv[0]+1); printf("0番目 引数1文字目のアドレス %p\n",&(argv[0][0])); printf("0番目 引数2文字目のアドレス %p\n",&(argv[0][1])); printf("1番目 引数 %s\n",argv[1]); printf("1番目 引数1文字目のアドレス %p\n",argv[1]+0); printf("1番目 引数2文字目のアドレス %p\n",argv[1]+1); printf("1番目 引数1文字目のアドレス %p\n",&(argv[1][0])); printf("1番目 引数2文字目のアドレス %p\n",&(argv[1][1])); } それぞれの 1文字目,2文字目のアドレスに一緒の値が表示されませんか?

関連するQ&A

  • ポインタについて

    こんにちは。「独習C」で独学している者です。その中の練習問題をやっていました。課題はコマンドラインから引数を受け取り各文字に1を加え暗号化して表示するというものでした。 自分で考え一応ちゃんと動くものが書けました。その後もっとシンプルにならないかと少しずつ余分な所を削っていき以下のようになりました。 #include <stdio.h> int main(int argc,char *argv[]) { char ch; if(argc != 2){ printf("引数が正しくありません"); exit(1); } else while(*argv[1] != '\0'){ printf("%c",*(argv[1]++) + 1); } return 0; } できた、できたと喜んでいたのですがソースをよく見ていると*(argc[1]++)の所を見てあれっと思いました。これでは文字列の二番目の要素からしか表示できないのではないのかと思ったのです。しかし動かすとちゃんと動くのです。ちゃんと1番目の要素も表示されるのです。自分としては++を消して次の行にargv[1]++を付け加えればいいと思ったのですがどうでしょうか?(←これでもちゃんと動きました)私のポインタに対する考え方が間違っているのでしょうか?よろしくお願いします。

  • ポインタについての質問など

    (1) プログラム引数を取る時の記述ですが…. (int argc, char *argv[]) (int argc, char **argv) 本によって記述がまちまちなんです. これらはどう違うのでしょうか? 特に後者の解釈の仕方がいまいち分からないので教えてください. 配列になってないように見えるのですが…. (2) 後者の記述(int argc, char **argv)で書かれたプログラムで ./program.exe okwave と引数を取ったとき,okwaveのoからeまでをfor文やwhile文でたどって何らかの処理をしたいのですが,どうすればいいのでしょうか? (3) ポインタには関係ありませんが,Windowsでncursesは使えないのでしょうか?

  • コマンドライン引数 *argv[]はなぜポインタ?

    C言語初心者です。 コマンドライン引数、 int main(int argc, char *argv[]) というのを最近勉強しましたが、引数2番目がポインタになっている理由について、 どなたか教えて下さい。 そういう仕様なんだから、それに従いましょう、ということでしょうか? int main(int argc, char argv[]) では、ダメなのでしょうか? このポインタでの引数渡しについて、 なんらかの納得のいく考え方をご存知の方がいらしたら、教えて下さい。 宜しくお願い致します。

  • 関数の引数の書き方。

    AとBのどちらの書き方でもよいのですか? 私が読んだ本(やさしいC)には、 Aパターンのみだったような? Aパターン ------------------ void main(int argc,char *argv[]) { int i; ・・・・ } Bパターン ------------------ void main(argc, argv) int argc; char *argv[]; { int i; ・・・・ } http://ash.jp/db/ora_c.htm

  • ポインタのポインタ

    #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv){ int i; if(argc != 2) { fprintf(stderr, "Usage: %s vector\n\tEx: %s 11110000\n", argv[0], argv[0]); return 1; } for(i=0;i<8;i++){ if(**argv == '0'){ printf("%d\n",i); } else{ printf("A%d\n",i); } argv++; } return 0; } コンパイルして./a.exe 10010011などと入力しても A0 A1 Segmentation Faultとなります。 どうすれば、 A1 0 ・・・省略 for文で回した8回分、出力が可能になるのか教えてください。 初歩的な質問ですいません。

  • 非常に基本的なポインタの使い方

    非常に基本的なところだと思いますが、ポインタの理解がうまくなく意図どおりのプログラムが書けません。 何らか引数を渡して(とりあえず文字列"hogehoge"を渡す)、そのポインタaをtest関数に渡して、ちゃんと"hogehoge"が渡っていれば「pass」と出力する 意図なんですが、どうもうまくいっていないようです。 ----------------------------- int test(char* a) { if(a == "hogehoge"){ printf("pass\n"); }else{ printf("ng\n"); } return 0; } int main(int argc, char* argv[]) { char* a = argv[0]; // "hogehoge"を渡しているとします。 test(a); return 0; } ----------------------------- 何がおかしいのか理解ができず、困っています。 ちなみに char* a = argv[0]; の箇所を単純に char* a = "hogehoge"; とした場合はうまくいくので、余計に混乱しております。 どなたか、正解例をご教授いただけませんでしょうか。

  • main(int argc,char **argv[])の意味を教えて下さい

     今晩は、Cの初心者です宜しくお願いします。  main関数の引数で、int main(int argc,char **argv[])とint main(int argc,char *argv[])と書かれている場合がありますが、 「**argv」と「*argv」の意味の違いはどのようなもので、どのように使い分けるのでしょうか。 また、必ずポインタ型でとるという決まりでしょうか。 宜しくお願いします。

  • main の引数には const 付けた方が

    C言語での質問です。 引数を取るような main 関数は int main( int argc, char *argv[]){~} とされていますが、argvの指す文字列を変更する、というのはいくら何でもまずいので、 int main( int argc, const char *argv[]){~} あるいは int main( int argc, const char const * const * argv){~} の方がいいのではないでしょうか? 何故、constを付けない形が出回っているのでしょうか?

  • C言語のプログラム(ポインタについて)

    /* コマンドライン引数で与えられた長い文字列を長さ10文字ずつに分割してp[100][11]に順番に入れ,表示するプログラム <例>./a.out 1234567890ABCDEFG p[1] = "1234567890" p[2] = "ABCDEFG" */ #include <stdio.h> int main(int argc, char **argv) { int i, len; char *str; len=0; for(i=1; i<argc; i++){ len += strlen(argv[i]); } if((str=(char *) malloc(len+1))==NULL){ perror("malloc"); exit(1); } strncpy(str,argv[1],10); for(i=2; i<argc; i++){ strcat(str,argv[i]); } printf("p[%d] = %s\n", i-1, str); } 上に示した処理をするプログラムを作成したいのですが、 今のソースは単に10文字表示するだけで、ここからどうしたらいいのか見当がつきません・・・・・。 なのでどういった改良をすればよいのか教えていただければ助かります。 /*配列aにファイルから値を読み込み、それを表示した後*/ /*配列に格納された値を下に1つずつずらして表示するプログラム(ポインタを使用して)を作成*/ /*(なお、一番上a[0]にはa[99]の値を入れる)*/ /*<例>*/ /*a[0] = 0 */ /*a[1] = 1 */ /*  ・ */ /*  ・ */ /*a[98] = 98*/ /*a[99] = 99*/ /*a[0] = 99 */ 1つずらしたもの /*a[1] = 0 */ /*  ・ */ /*  ・ */ /*a[98] = 97*/ /*a[99] = 98*/ (読み込むファイル[file-100.dat]には0~99の数字が1つずつ改行しながら入っています) できればこちらにも答えていただければ嬉しいです。 この問のソースは書きませんが、ファイルを配列に読み込んで表示してからの処理がいまいちわからず困っています。 すばやい御回答お待ちしております。よろしくお願いします。

  • C言語でコマンドラインの引数について。

    コマンドラインで引数をわたす基本的なプログラムは main(int argc,char *argv[]){....] ですよね。 今回実行時に、 >実行ファイル名 123 + 233 といれたら、123+233を計算してくれるプログラムを作ろうとしています。 その場合、main(int argc,int *argv[]){} としたら、argv[1]に123が入って、argv[2]に+が入って、argv[3]に233が、入るというわけではないんでしょうか? とりあえず、確認で #include<stdio.h> main(int argc,int *argv[]) { printf("%d\n%d\n",argv[1],argv[3]); } としてみたんですが、実行結果は、とても長い数字がでてきてきました。 なにがいけないのか教えてください。 お願いします。 あとWindows MEでVC++6を使ってます。

専門家に質問してみよう