码迷,mamicode.com
首页 > 编程语言 > 详细

关于指针与数组定义的字符串

时间:2016-07-22 21:01:35      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

  1. 将指针指向一串字符串(char *a = "abcdef";),可以以 “printf("a[2] = %c\n", a[2])“ 这种方式输出字符串中第三个字符。但不能这样 “a[2] = G妄图将字符串中的第三个字符‘c‘改为‘G‘。至于为什么,我现在是不知道了。先看代码
     1  #include <stdio.h>
     2  
     3  int main(void)
     4  {
     5      char *a = "abcdef";
     6      printf("a[2] = %c\n", a[2]);//可以正确输出a[2] = c
     7      a[2] = G;//到了这里程序不正常结束。
     8  
     9      printf("In main = %s\n",a);
    10      return 0;
    11  }

     做一点小小的改动,就可以在做到更改字符串中的某个位置的字符了。看代码:

     #include <stdio.h>
     
     int main(void)
     {
         char a[10] = "abcdef"; ------> 修改这儿.
         printf("a[2] = %c\n", a[2]);//正确输出a[2] = c
         a[2] = G;
     
         printf("In main = %s\n",a);//正确输出In main = abGdef
         return 0;
     }

    这两个代码的小小差距映射出的东西很有趣。给他们加点东西继续看看。

  2. 这里看看在函数调用。
     1  #include <stdio.h>
     2  
     3  void change_piont(char*);
     4  
     5  int main(void)
     6  {
     7      char *a = "abcdef";
     8      printf("a[2] = %c\n", a[2]);
     9  
    10      change_piont(a);
    11      printf("In main = %s\n",a);
    12      return 0;
    13  }
    14  
    15  void change_piont(char *a) 
    16  {
    17      printf("a[2] = %c\n",a[2]);//这里可以输出a[2] = c,说明这个函数里可以访问指针a。
    18      a[2] = g;//这里就出现错误。
    19  
    20  }
    21  /**************************************
    22   * 输出结果:
    23   * a[2] = c
    24   * a[2] = c
    25   * Segmentation fault (核心已转储)
    26   * ************************************/

     和第一点一样,当尝试改变字符串中某个位置的字符,就出现错误。像第一点一样,我们改动一下。

     1  #include <stdio.h>
     2  
     3  void change_piont(char*);
     4  
     5  int main(void)
     6  {
     7      char a[10] = "abcdef";  ---------------> 改的仅仅是这行.
     8      printf("a[2] = %c\n", a[2]);
     9  
    10      change_piont(a);
    11      printf("In main = %s\n",a);
    12      return 0;
    13  }
    14  
    15  void change_piont(char *a) 
    16  {
    17      printf("a[2] = %c\n",a[2]);
    18      a[2] = g;
    19  
    20  }

     

    意料之中,和第一点一样,将指针改为数组后,就可以正常替换了。
    到这里,我们可以先来个小总结了。
    不知道你对上面的输出有没有注意到:对于初始化为指向一个句子的指针,可以用数组记号(即a[i])输出这个句子中任意一个字符。我们知道,输出数组中的值就是用数组记号来完成的。也就是说,对于定义char a[10] = "abcdef"char *a = "abcdef" 都可以用数组记号a[2]输出字符串abcdef的第三个字符:c 。那么,是不是char a[10] 与 char *a 定义的abcdef 含义都一样呢?非也,首先,从上面的代码例子中可以看出,可以修改数组定义的字符串的某个序列的字符,比如在第二个代码中a[2] = G 修改了字符串的第三个字符。而指针指向的字符串,不能修改其中的的字符。只能引用。还有,当你用sizeof(a)来分别输出数组a 和 指针 a ,就会发现更大的不同。当然,对于指针,sizeof(a)输出的是存储a指针的内存大小(一般是8,决定于你的系统)。如果你想输出a指针指向的地址的字节大小,就要这样sizeof(*a),对于这篇文章的例子,就是输出1 ,char 型就是占用一个字节啊。
    真正的问题还在,为什么用指针定义的字符串不能用指针记号a[i] 修改其中字符的值?
            指针指向的字符串是一个整体的常量。你见过有人能修改常量的么?其实还有更深层含义的东西,我隐约存在着疑问:用a[i] 可以输出这个字符串常量中的某个字符,这说明了可以知道这个字符所在的地址,那通过这个地址为什么不能修改这个地址上的值?我们平时的变量值不都是通过地址来改变的吗?
    个人猜测:a[i] 也是一个常量,常量也有地址,但通过地址就不能修改常量。

  3.  给分配了内存的指针赋值,再看看可不可以改变。
     #include <stdlib.h>
     #include <stdio.h>
     
     int main(void)
     {
         int number = 10; 
         char *a = (char*)calloc(number, sizeof(char));
         printf("a_size = %d\n", sizeof(a));
     
         for(int i = 0 ; i < number ; ++i){
             char b = a;
             a[i] = b+i;//用b++会失败,每次b的值都会在上面一句重新初始化。
         }
         printf("a = %s\n", a); 
         printf("a_size1 = %d\n", sizeof(a));
     
         a[2] = B;
         printf("a1 = %s\n", a); 
     
         free(a);
         a = NULL;
     
         //change_piont(a);
        // printf("In main = %s\n",a);
         return 0;
     }
     
     /**************************************
      * a_size = 8
      * a = abcdefghij
      * a_size1 = 8
      * a1 = abBdefghij
      * ************************************/

    给上面代码怎增加两行:

    1 scanf("%s",a);
    2 printf("a2 = %s\n", a);

    可以利用scanf函数对a指向的值任意修改(当然,不能超过number)。
    问题似乎明确了起来了,再看看:

     1  #include <stdio.h>
     2  
     3  int main(void)
     4  {
     5      char a = a;
     6      char *pA = &a; 
     7      pA[0] = A;
     8      printf("a = %c\n",a);
     9      printf("*pA = %c\n",*pA);
    10  
    11      return 0;
    12  }
    13  /*************
    14   * a = A
    15   * *pA = A
    16   * **********/

     

    终于明白了。当这样来初始化:char *a = "abcdef",实质上就是给指针a指向了一个字符串常量!!!!!而且这个字符串的每一个字符都是常量,不能修改这些常量,也不能这样scanf("%s",a)!!!!如果给指针a指向了一个变量,就可以修改!!

     

关于指针与数组定义的字符串

标签:

原文地址:http://www.cnblogs.com/busui/p/5695407.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!