숯 * s 및 문자 []

따라서 의도적으로 다시 물건 포인터와 배열, 비교적 간단한 다른 유형의 배열로 탐구, C 언어 포인터의 유연성으로 인해, 선두 포인터는 배열의 사용을 대체 할 수있는, 또는 조합이 포인터와 배열의 많은 혼란을 주도 문자 포인터와이 두 가지의 캐릭터의 혼란 배열입니다. . . 다음은이 두 가지 고통과 슬픔 무엇인지를 분석하기 시작했다. . .

 자연 1 개 어레이

   배열 요소의 복수의 집합이고, 상기 메모리 유닛의 어드레스에 연결된 분배 장치는 첨자 다른 요소들에 의해 액세스 될 수있다. .

 2 포인터.

   또한 포인터 변수가 있지만,이 메모리 셀에 저장되고, 다른 위치에 어드레스를 식별한다. . 주소가 정수, 32 비트 플랫폼이기 때문에, 기본 32 비트 포인터이다. .

 3 포인터?

   소수점 데이터 유형은 직접 다른 유닛 어드레스 포인터 변수 저장 부에 저장된 것을 의미한다.

   INT P * // 메모리 단위 어드레스에 저장되는 데이터의 P 형이있는 변수는 정수이고

           * Q를 떠; // ........................................ 플로트

           이 주소를 저장하기 때문에 관계없이 그 데이터 포인트의 종류, 포인터 변수 자체는 항상 정수입니다.

    4 문자 배열. . .

        그대로 배열 수단, 배열 요소의 문자들이다. . 사실,이 본질적인 의미입니다.

         숯 STR [10]; 

         그것은 10 개 요소와 요소 유형의 문자 배열을 정의합니다.

         언제 C 언어로 정의 된 변수를 초기화 할 수 있습니다.

         숯 STR [10] = { "안녕하세요"};

         컴파일러는 구문 만나면 배열 안녕하세요 \ 0 의해 제 소자로부터 str에 기입한다. .

         C 언어는 실제 문자열 형식이 없기 때문에이 요소가 연속 해결할 수 있기 때문에, 그것은 문자의 문자열 배열로 나타낼 수있다, 그것은 충분했다.

         C 언어 어레이는 제 어드레스 [0] 어드레스, 즉 STR STR 소정 메모리 위치의 어레이를 나타낸다 STR = [0];

         의 printf ( "%의 S", STR) 왜 제 주소 문자열을 출력 할 수있다. .

          자연 상수 C 언어 문자열에 키가 있기 때문에 훨씬 더 어려운 초보자의 문제를 이해하는 것입니다 주소의 표현은 사실이다. . .

          예를 들면 :

          * CHAR S;

          S = "중국";

          왜 당신은 문자열 포인터 변수를 할당 할 수 있습니다. .

          이 불일치 그것의 형식이 아닙니다? ? ?

          이것은 위에서 언급 한 키입니다. .

          C 언어 컴파일러는 "중국"의 경우,은 0x3000 0x3001 0x3002 0x3003 0x3004 함 0x3005의 메모리에 주소 문자열 상수 지정합니다.

          S = "중국", 무슨 의식, 그래, 주소.

          사실, S의 진정한 의미 = "중국"=은 0x3000;

          이 봐, 당신은 중국이 문자열로 간주하는 듯했으나 컴파일러 주소은 0x3000으로 볼, 즉 문자열 상수의 성능의 본질이다의 첫 번째 문자의 주소의 대표입니다. . . . . . . . . .

          S =은 0x3000

          쓰기는 직관적 인 의미에 맞춰 더 많은 것 같다. . .

          이 문제를 이해합니다. .

          그래서 %들, 그 원리는 실제로 출력 문자열의 printf ( "% s '에,들) 문자열로 첫 번째 주소입니다 실제로 전달이 문자열의 저장의 주소입니다. . .

          등

        #INCLUDE <STDIO.H>

       ) (대표 값 int
       {

         * CHAR S;
         S = "안녕하세요";
         의 printf ( "% P \ 없음", S);
         0을 반환;
      }

                          

          

 

      중국 ""첫 번째 주소 인,의의 =의 0x00422020 참조

      따라서,의 printf ( "%의 S"0x00422020)도 동등한. .

     

       문자의 배열 :

       숯 STR [10] = "안녕하세요";

       이미 말한 것처럼, STR STR = [0], 제 주소 "안녕하세요"와 동등하다. .

       그러므로의 printf ( "%의 S", STR)도 본질적으로는 printf ( "% S의"주소 ");

        C 언어 스트링 작업은 최종 문자열의 본질은, 메모리 셀에 저장되어있는 선두 어드레스에 의해 수행된다. . .

    5 char * 부여 char a [];

       * CHAR S;

       [η]는 char;

       스트링의 이전에 제 1 어드레스 대표 언급이 포인터의 주소 문자열도 (사실, 선두 어드레스)에 저장되는 경우, 즉 첫 번째 문자의 주소,이 어드레스 데이터는 문자 단위

   이것은 또한의 지적 문자와 일치합니다.

      따라서 S는 A =;

       그러나이 아니라 = s의;

       배열 이름 포인터에 복사 할 수 C 언어 어드레스를 나타내고 있지만,이 어레이 이름에 할당 될 수없고, 그 일정 유형이며, 이는 변경 될 수 없다. .

       물론이 될 수있다 :
        A [] = "안녕하세요"를 숯불;

        * CHAR는 A = S;

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

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

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

        字符指针可以用 间接操作符 *取其内容,也可以用数组的下标形式 [ ],数组名也可以用 *操作,因为它本身表示一个地址 。。

       比如 printf("%c",*a);  将会打印出 'h'

       char * 与 char a[ ] 的本质区别:

       当定义 char a[10 ]  时,编译器会给数组分配十个单元,每个单元的数据类型为字符。。

       而定义 char *s 时,  这是个指针变量,只占四个字节,32位,用来保存一个地址。。

       sizeof(a) = 10 ;

       sizeof(s)  = ?

       当然是4了,编译器分配4个字节32位的空间,这个空间中将要保存地址。。。

        printf("%p",s);

        这个表示 s 的单元中所保存的地址。。

        printf("%p",&s);

        这个表示变量本身所在内存单元地址。。。。,不要搞混了。。

        用一句话来概括,就是 char *s 只是一个保存字符串首地址的指针变量, char a[ ] 是许多连续的内存单元,单元中的元素为char ,之所以用 char *能达到

 char a  [ ] 的效果,还是字符串的本质,地址,即给你一个字符串地址,便可以随心所欲的操所他。。但是,char* 和 char a[ ] 的本质属性是不一样的。。

    

     6      char **  与char  * a[ ] ;

            先看 char  *a [ ] ;

            [] 때문에하는 *] 결합하여 상기 제 1 및보다 높은 우선 순위, 그 배열의 요소의 배열 어드레스를 저장 숯 * 숯 *가 가변 앞에서 설명한하였습니다. .

            所以 문자 *는 [] = { "중국", "프랑스어", "미국", "독일어"};

            같은 문구를 볼 수있는 동안, 배열 요소는,는 sizeof (a)는 얼마나 많은 사람들이 생각하는 다섯 개 단어 6 + 7 + 8 + 7 = 28의 메모리의 총 바이트 수를 설명하는 문자열입니다 ;

            그러나, 실제로는 sizeof는 (a) = 16;

            이미 말한 것처럼 이유 문자열 상수의 본질은 해결하는 배열 요소 포인터 * 4 바이트이므로 4 개 요소 포인터 변수 총 16 바이트 숯불

            예를 들어 봐 :

            #INCLUDE <STDIO.H>

   INT 주 ()
   {
    문자 *는 [] = { "중국", "프랑스어", "미국", "독일어"};
    의 printf ( "%의 P %의 P %의 P % 포인트 \ n을"A [0], A [1], A [2], A [3]);

    0을 반환;
   }

    

      어레이가 아닌 문자열 문자열 자체의 처음 주소 네에서 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