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


    1. 将指针指向一串字符串(char *a = "abcdef";),可以以 “printf("a[2] = %c ", 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
      ", a[2]);//可以正确输出a[2] = c
       7      a[2] = 'G';//到了这里程序不正常结束。
       8  
       9      printf("In main = %s
      ",a);
      10      return 0;
      11  }

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

       #include <stdio.h>
       
       int main(void)
       {
           char a[10] = "abcdef"; ------> 修改这儿.
           printf("a[2] = %c
      ", a[2]);//正确输出a[2] = c
           a[2] = 'G';
       
           printf("In main = %s
      ",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
      ", a[2]);
       9  
      10      change_piont(a);
      11      printf("In main = %s
      ",a);
      12      return 0;
      13  }
      14  
      15  void change_piont(char *a) 
      16  {
      17      printf("a[2] = %c
      ",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
      ", a[2]);
       9  
      10      change_piont(a);
      11      printf("In main = %s
      ",a);
      12      return 0;
      13  }
      14  
      15  void change_piont(char *a) 
      16  {
      17      printf("a[2] = %c
      ",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
      ", sizeof(a));
       
           for(int i = 0 ; i < number ; ++i){
               char b = 'a';
               a[i] = b+i;//用b++会失败,每次b的值都会在上面一句重新初始化。
           }
           printf("a = %s
      ", a); 
           printf("a_size1 = %d
      ", sizeof(a));
       
           a[2] = 'B';
           printf("a1 = %s
      ", a); 
       
           free(a);
           a = NULL;
       
           //change_piont(a);
          // printf("In main = %s
      ",a);
           return 0;
       }
       
       /**************************************
        * a_size = 8
        * a = abcdefghij
        * a_size1 = 8
        * a1 = abBdefghij
        * ************************************/

      给上面代码怎增加两行:

      1 scanf("%s",a);
      2 printf("a2 = %s
      ", 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
      ",a);
       9      printf("*pA = %c
      ",*pA);
      10  
      11      return 0;
      12  }
      13  /*************
      14   * a = A
      15   * *pA = A
      16   * **********/

      终于明白了。当这样来初始化:char *a = "abcdef",实质上就是给指针a指向了一个字符串常量!!!!!而且这个字符串的每一个字符都是常量,不能修改这些常量,也不能这样scanf("%s",a)!!!!在函数调用中,如果给指针a指向了一个变量,就可以修改,但要注意,修改的是这个变量的值,而不是指针本身,就是你不能将指针指向新的地址。如果你想将指针指向新的地址,就需要将存储指针的地址传递为变元。要努力区分:存储指针的地址和指针村存储的地址。否则指针难以学好。

       

  • 相关阅读:
    SpringMVC:JSON讲解
    SpringMVC:文件上传和下载
    字符串的使用
    python中的作用域与名称空间
    深、浅copy
    代码块与小数据池之间的关系
    关于敏感字符的筛选替换
    列表的增、删、改、查
    最简三级菜单
    python2.x与python3.x的区别
  • 原文地址:https://www.cnblogs.com/busui/p/5695407.html
Copyright © 2020-2023  润新知