char * s and chars []

Due to the flexibility of the C language pointer, leading pointers can replace the use of an array, or in combination, led to the confusion of many of these pointers and arrays, therefore, deliberately again delves into this stuff pointers and arrays, an array of other types of relatively simple confusing array of character pointers and character of these two. . . The following began to analyze what these two pains and sorrows. . .

 1 array of nature

   An array is a collection of a plurality of elements, the distribution unit connected to the address in the memory unit can be accessed by different elements which subscripts. .

 2 pointers.

   Also a pointer variable, but it is stored in a memory cell is identified other location address. . Because the address is an integer, 32-bit platform, the default is 32-bit pointer. .

 3 pointers?

   Point data type means that direct the other unit pointer address stored in the variable storage.

   int * p; // p type of data stored in the memory unit address is located variable is integer

           float * q; // ........................................ float

           Regardless of the type of data points for that, the pointer variable itself is always an integer, because it saves address.

    4 array of characters. . .

        Literally means an array, the array elements are characters. . Indeed, this is its essential meaning.

         char  str[10]; 

         It defines an array with ten elements and element type character.

         When you can initialize a variable defined in C language.

         char  str[10] = {"hello world"};

         When the compiler encounters the phrase, the array will str hello world \ 0-by fill from the first element. .

         Since the C language is no real string type, it can be represented by a string array of characters, because it addresses the elements is continuous, it was enough.

         C language array represents an array of a predetermined memory location where the first address is str [0] address, i.e. str = & str [0];

         The printf ( "% s", str); Why can output the string with the first address. .

          Because there is a key, in C language string constant in nature is actually a representation of address, which is a lot more difficult to understand for beginners problems. . .

          For example:

          char  *s ;

          s = "China";

          Why you can assign a string pointer variable. .

          This is not the type of inconsistency it? ? ?

          This is the key mentioned above. .

          C language compiler will assign an address string constant, if "China", in memory of 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005.

          s = "China", what consciousness is, yes, address.

          In fact, the true meaning of s = "China" = 0x3000;

          Look at it, you put China seen as a string, but see it as the compiler address 0x3000, that is the essence of the performance of a string constant is representative of the address of its first character. . . . . . . . . .

          s = 0x3000

          Write seems more in line with the intuitive meaning. . .

          Understand this problem. .

          So% s, its principle is actually output string, printf ( "% s", s) the first address by a string; it is actually passed is the address of the string s saved. . .

          such as

        #include <stdio.h>

       int main ()
       {

         char *s;
         s = "hello";
         printf("%p\n",s);
         return 0;
      }

                          

          

 

      See s = 0x00422020, which is the "China" the first address

      Therefore, printf ( "% s", 0x00422020); also equivalent. .

     

       An array of characters:

       char  str[10] = "hello";

       As already said, str = & str [0], is equivalent to "hello" the first address. .

       Therefore printf ( "% s", str); also essentially printf ( "% s", address ");

        C language string operations are performed by the first address it is stored in memory cells, which is the essence of the ultimate string. . .

    5 char * given char a [];

       char  *s;

       char  a[ ] ;

       As mentioned earlier the first address representative of a string, and this pointer s address string is also saved (in fact, the first address), i.e., the address of the first character, this address data is a character unit,

   This is also consistent with pointed s char.

      Therefore s = a;

       But not a = s;

       C language array name can be copied to the pointer indicates the address, but it can not be assigned to the array name, it is a constant type, it can not be modified. .

       Of course, this may be:
        char A [] = "Hello";

        char *s =a;

        for(int i= 0; i < strlen(a) ; i++)

             printf("%c", s[i]);

         Or printf ( "% c", * s ++);

        Character pointer can indirectly operator * whichever content, can also be used in the form of an array index [] array name can also be used * operation, because it represents itself an address. .

       For example printf ( "% c", * a); will print 'h'

       char * and char a [] the essential difference:

       When defining char a [10], the compiler will assign an array 10 units, each unit of data type character. .

       And defining char * s, which is a pointer variable, only four bytes, 32-bit, for holding an address. .

       sizeof(a) = 10 ;

       sizeof(s)  = ?

       4, of course, the compiler allocates 4 bytes of the 32-bit space, this space will be saved address. . .

        printf("%p",s);

        S represents a unit of the stored address. .

        printf("%p",&s);

        This in itself represents a memory unit address where the variable. . . . Do not confuse. .

        Be summed up, is stored char * pointer variable S is only a first address of the string, char a [] is the number of successive memory unit, the unit element of char, char * can be achieved with the reason

 char a [] effect, or the nature of the string, address, give you a string address, it can be arbitrary exercise by him. . However, char * and char a [] essential attribute is not the same. .

    

     6 char ** given char * a [];

            Look char * a [];

            Because [] is a higher priority than the first and so * [] combine, he was an array of elements in the array is char *, char * is mentioned in front of a variable, save the address. .

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

            Over the same phrase can be seen, the array element is a string, sizeof (a) is how much, people think is five words account for the total number of bytes in memory of 6 + 7 + 8 + 7 = 28 ;

            However, in fact, sizeof (a) = 16;

            Why, as already said, is the essence of string constants address, a array elements char * pointer, the pointer variable total of four bytes, so four elements is 16 bytes of

            Look at an example:

            #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]);

    return 0;
   }

    

      You can see the four elements in the array holds four memory address, which represents the four addresses in the first address four of the string, not the string itself. . .

      Thus sizeof (a) 16 of course. .

      注意这四个地址是不连续的,它是编译器为"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);

     }

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

Guess you like

Origin www.cnblogs.com/double-orange/p/11069469.html