するchar * sおよび文字[]

そのため、故意に再びこのようなものポインタと配列、比較的単純な、他の種類の配列掘り下げ、C言語のポインタの柔軟性のため、大手のポインタは、アレイの使用を置き換えることができ、または組み合わせて、これらのポインタと配列の多くの混乱につながりました文字ポインタとこれら二つの文字の混乱配列。以下は、どのようなこれら二つの痛みと悲しみを分析し始めました。

 自然の1列

   アレイは、複数の要素の集合である、メモリ・ユニット内のアドレスに接続された分配ユニットは、添え字異なる要素によってアクセスすることができます。

 2つのポインタ。

   また、ポインタ変数が、それは、メモリセルに格納されているが、他の場所のアドレスを特定します。アドレスは整数、32ビットプラットフォームであるため、デフォルトでは32ビット・ポインタです。

 3つのポインタ?

   小数点データ型は、直接他のユニットのポインタアドレスを変数記憶部に記憶されていることを意味します。

   INT * P; //メモリ・ユニット・アドレスに格納されたデータのP型が配置されている変数は、整数であります

           * Qフロート; // .............................フロート

           それはアドレスを保存しているためにかかわらず、そのためのデータポイントの種類の、ポインタ変数自体は、常に整数です。

    文字の4アレイ。

        文字通り配列を意味し、配列の要素は文字です。確かに、これは、その本質的な意味があります。

         文字列str [10]。 

         これは、10の要素と要素の文字型の配列を定義します。

         するときは、C言語で定義された変数を初期化することができます。

         文字列str [10] = { "Hello World" の}。

         コンパイラは、フレーズを検出すると、配列は、Hello Worldの\ 0-による最初の要素から記入をstrます。

         C言語は本当の文字列型ではないので、それは要素に対処するので、それは、文字列の配列で表すことができる連続的である、それは十分でした。

         C言語配列[0]先頭アドレス[0]アドレス、即ちSTR =&STR STRである所定のメモリ位置のアレイを表します。

         printf(「%sの」、STR);なぜ最初のアドレスを出力文字列をすることができます。

          自然の中で一定のC言語の文字列のキーがあるので、より多くの困難な初心者の問題を理解することであるアドレスの表現は、実際にあります。

          例えば:

          char * sの。

          S =「中国」。

          なぜあなたは、文字列のポインタ変数を割り当てることができます。

          これは、それは矛盾のタイプではありませんか?

          これは、上記のキーです。

          C言語コンパイラは、「中国」であれば、0x3000の0x3001 0x3002 0x3003 0x3004 0x3005のメモリに、アドレス文字列定数が割り当てられます。

          S =「中国」、どのような意識はい、アドレス、です。

          実際には、= 0x3000のS =「中国」の本当の意味。

          それを見て、あなたは文字列として見た中国を置くが、文字列定数のパフォーマンスの本質は、その最初の文字のアドレスの代表であることをコンパイラアドレス0x3000の、としてそれを参照してください。

          S = 0x3000の

          書き込みは、直感的な意味を持つのラインでより多くのです。

          この問題を理解します。

          だから、%sが、その原理は、実際に出力文字列、printfの(「%sの」、s)は、文字列による最初のアドレスであり、実際に渡され、それは文字列s保存のアドレスです。

          そのようなものとして

        書式#include <stdio.hに>

       INTメイン()
       {

         char * sの。
         S = "こんにちは";
         printf( "%Pを\ n"、S);
         0を返します。
      }

                          

          

 

      「中国」の最初のアドレスでのS =の0x00422020を参照してください。

      したがって、のprintf( "%sの" 0x00422020)にも同等。

     

       文字の配列:

       文字列str [10] = "こんにちは"。

       既に述べたように、STR =&STR [0]は、最初のアドレス「ハロー」に相当します。

       このためのprintf( "%sの"、STR);本質的のprintf( "%sの" アドレス「)。

        C言語の文字列操作は、最終的な文字列の本質であり、それはメモリセルに記憶されている第1のアドレスによって行われます。

    5  char *  与 char  a[ ];

       char * sの。

       [] char型。

       先に述べたように最初の列のアドレスを代表し、このポインタのアドレス列も(実際に最初のアドレス)に保存され、すなわち、最初の文字のアドレスは、このアドレスデータは、文字単位であります

   また、これはsの尖った文字と一致しています。

      従ってSは=。

       しかし、ではない=秒;

       C言語配列名はポインタにコピーすることができるアドレスを示し、それは配列名に割り当てることができない、それは一定のタイプであり、それを変更することはできません。

       もちろん、これは次のようになります。
        [] =「こんにちは」をchar型。

        char * S = A;

        (私は++; iが(A)STRLENを<I 0 = INT)のために

             printf( "%のC"、S [I])。

         またはのprintf( "%cの"、* S ++);

        それはアドレス自体を表すので、文字ポインタは、間接的演算子*方コンテンツ、配列インデックス[]配列名の形でも使用することができるが、また、*操作を使用することができることができます。

       例えば、printfのため( "%のC"、* a)は、 'H' を出力します

       char *と[]本質的な違いを文字:

       [10]チャー定義する場合、コンパイラは、アレイ10単位、データ型文字の各ユニットに割り当てられます。

       そしてアドレスを保持するため、ポインタ変数であるチャー* Sは、唯一の4バイト、32ビットを定義します。

       sizeof(A)= 10。

       sizeof(S)=?

       図4は、もちろん、コンパイラは、この空間がアドレスを保存され、32ビット空間の4つのバイトを割り当てます。

        printf( "%のP"、S);

        Sは、格納されたアドレスの単位を表します。

        printf( "%のP"、&S)。

        これ自体は、メモリユニットのアドレス変数を表します。混同しないようにしてください。

        []の連続するメモリ部、チャーの単位素子、チャー*の数が理由で達成することができるされているCHAR、Sは、文字列の最初のアドレスであるCHAR *ポインタ変数に格納され、加算され

 []効果、または文字列の性質をchar型、アドレス、あなたの文字列のアドレスを与え、それは彼が任意運動することができます。しかし、CHAR *と[]は必須属性をchar型は同じではありません。

    

     6      char **  与char  * a[ ] ;

            [] char *型に見えます。

            [] * []兼ね備え最初ので、彼は、配列の要素の配列だったよりも高い優先順位がcharです*、char型の*は、変数の前に記載されているので、アドレスを保存します。

            CHAR所以* [] = { "中国"、 "フランス語"、 "アメリカ"、 "ドイツ"}。

            同じフレーズを見ることができる上、配列要素は、はsizeof(a)はどのくらい、人々が考えるある5つの単語が6 + 7 + 8 + 7 = 28のメモリの総バイト数を占めている文字列です;

            しかし、実際には、はsizeof(A)= 16。

            なぜ、既に述べたように、文字列定数の本質はそう四つの要素は16バイトであり、配列要素のchar *ポインタ、4バイトのポインタ変数合計アドレスであります

            例を見てください:

            書式#include <stdio.hに>

   INTメイン()
   {
    CHAR * [] = { "中国"、 "フランス語"、 "アメリカ"、 "ドイツ"}。
    printf( "%のP%のP%のP%のPを\ n"、[0]、[1]、[2]、[3])。

    0を返します。
   }

    

      あなたは、配列が文字列ではなく、文字列自体の最初のアドレス4に4つのアドレスを表している4つのメモリアドレスを、保持している4つの要素を見ることができます。

      こうしてはsizeof(a)はもちろん16。

      注意这四个地址是不连续的,它是编译器为"China","French","America","German" 分配的内存空间的地址, 所以,四个地址没有关联。

         #include <stdio.h>

   int main()
   {
   char *a [ ] = {"China","French","America","German"};

           printf("%p %p %p %p\n",a[0],a[1],a[2],a[3]); //数组元素中保存的地址
   printf("%p %p %p %p\n",&a[0],&a[1],&a[2],&a[3]);//数组元素单元本身的地址

   return 0;
   }

           

      可以看到 0012FF38 0012FF3C 0012FF40 0012FF44,这四个是元素单元所在的地址,每个地址相差四个字节,这是由于每个元素是一个指针变量占四个字节。。。

       char **s;

       char **为二级指针, s保存一级指针 char *的地址,关于二级指针就在这里不详细讨论了 ,简单的说一下二级指针的易错点。  

       举例:

       char *a [ ] = {"China","French","America","German"};

       char **s =   a;

       为什么能把 a赋给s,因为数组名a代表数组元素内存单元的首地址,即 a = &a[0] = 0012FF38;

       而 0x12FF38即 a[0]中保存的又是 00422FB8 ,这个地址, 00422FB8为字符串"China"的首地址。

       即 *s = 00422FB8 = "China";

         这样便可以通过s 操作 a 中的数据

      printf("%s",*s);

      printf("%s",a[0]);

      printf("%s",*a);

      都是一样的。。。

      但还是要注意,不能a = s,前面已经说到,a 是一个常量。。

      再看一个易错的点:

      char **s = "hello world";

      这样是错误的,

       因为  s 的类型是 char **  而 "hello world "的类型是 char *

       虽然都是地址, 但是指向的类型不一样,因此,不能这样用。,从其本质来分析,"hello world",代表一个地址,比如0x003001,这个地址中的内容是 'h'

  ,为 char 型,而 s 也保存一个地址 ,这个地址中的内容(*s) 是char * ,是一个指针类型, 所以两者类型是不一样的。 。。

  如果是这样呢?
  char  **s;

       *s = "hello world";

       貌似是合理的,编译也没有问题,但是 printf("%s",*s),就会崩溃

       why??

      咱来慢慢推敲一下。。

       printf("%s",*s); 时,首先得有s 保存的地址,再在这个地址中找到 char *  的地址,即*s;

      举例:

       s = 0x1000;

      在0x1000所在的内存单元中保存了"hello world"的地址 0x003001 , *s = 0x003001;

      这样printf("%s",*s);

      这样会先找到 0x1000,然后找到0x003001;

      如果直接 char  **s;

      *s = "hello world";

       s 变量中保存的是一个无效随机不可用的地址, 谁也不知道它指向哪里。。。。,*s 操作会崩溃。。

       所以用 char **s 时,要给它分配一个内存地址。

      char  **s ;

      s = (char **) malloc(sizeof(char**));

      *s =  "hello world";

      这样 s 给分配了了一个可用的地址,比如 s = 0x412f;

      然后在 0x412f所在的内存中的位置,保存 "hello world"的值。。

    再如:

    #include  <stdio.h>

   void  buf( char **s)

    {

           *s = "message";

    }

    int main()

     {

        char *s ;

        buf(&s);

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

     }

    二级指针的简单用法。。。。,说白了,二级指针保存的是一级指针的地址,它的类型是指针变量,而一级指针保存的是指向数据所在的内存单元的地址,虽然都是地址,但是类型是不一样的。。。

おすすめ

転載: www.cnblogs.com/double-orange/p/11069469.html