zoukankan      html  css  js  c++  java
  • 字符串指针和字符数组的区别

    用字符数组和字符指针变量都可实现字符串的存储和运算。但是两者是有区别的。在使用时应注意以下几个问题:

    1.     字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘’作为串的结束。字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。

    2.     对字符串指针方式

    char *ps="C Language";

    可以写为:

        char *ps;

    ps="C Language";

    而对数组方式:

        static char st[]={"C Language"};

    不能写为:

        char st[20];

        st={"C Language"};

    而只能对字符数组的各元素逐个赋值。

         从以上几点可以看出字符串指针变量与字符数组在使用时的区别,同时也可看出使用指针变量更加方便。

    当一个指针变量在未取得确定地址前使用是危险的,容易引起错误。
    一个错误的例子,如下:       
               char *name;
               scanf("%s",name);
               printf("%s",name); 
     有的编译器虽然也能通过,但这是错误的,因为是个指针,定义时指向不可用的地址。解决这个问题有两种方法:用数组的方法或给字符针针分配内存空间的方法。
               数组的方法:
                     char name[20];
                     scanf("%s",name);
                     printf("%s",name); 
         
            给字符针针分配内存空间的办法: 
                     char *name;
                     name=(char*)malloc(50);      //此时name已经指向一个刚刚分配的地址空间。
                     scanf("%s",name);
                     printf("%s",name);

    但是对指针变量直接赋值是可以的。因为C系统对指针变量赋值时要给以确定的地址。

    3.int  main()
    {
     char str1[40]="hello world!";     //char *str1="hello world!";
     str1[4]='A';                      //若str1是指针型的,编译通过,但运行是此处会段错误
     printf("%s ",str1);
     return 0; 
    }


           数组和指针都可以在它们的定义中用字符串常量进行初始化,尽管看上去一样,底层的实现机制却不相同。

           定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间,除非在定义的同时赋值给指针一个字符串常量进行初始化。例如:下面的定义创建了一个字符串常量(为其分配了内存):

           char *p=”abcdefg”;

           注意只有对字符串常量才是如此,不能指望为浮点数之类的常量分配空间,如:

           Float *p=3.14;  /*错误,无法通过编译*/

    下面结合一个实例谈谈初始化指针时创建的字符串常量与数组中的字符串的区别:

    1. 在ANSI C中,初始化指针时所创建的字符串常量被定义为只读。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。在有些编译器中,字符串常量被存放在只允许读取的文本段中,以防止它被修改。
    2. 数组也可以用字符串常量进行初始化:

           Char a[]=”abcdefg”;

           如指针相反,由字符串常量初始化的数组是可以修改的。其中的单个字符在以后可以改变。

           下面是一个在vc6中的一个例子,完成将一个字符串中的所有大写字母全部转换为小写字母的功能:

    [cpp] view plain copy
     
    1. View Code  
    2.  1 #include<iostream.h>  
    3.  2 #include<ctype.h>  
    4.  3   
    5.  4  /******************************************************************************/  
    6.  5 /* 
    7.  6  *    Convert a string to lower case 
    8.  7  */  
    9.  8   
    10.  9 int strlower(char *string)  
    11. 10 {  
    12. 11     if(string==NULL)  
    13. 12     {  
    14. 13         return -1;  
    15. 14     }  
    16. 15   
    17. 16     while(*string)  
    18. 17     {  
    19. 18         if(isupper(*string))  
    20. 19             *string=tolower(*string);  
    21. 20         string++;  
    22. 21     }  
    23. 22     *string='';  
    24. 23     return 0;  
    25. 24 }  
    26. 25 /*char *strlower(char *string) 
    27. 26 { 
    28. 27     char    *s; 
    29. 28  
    30. 29      
    31. 30  
    32. 31     if (string == NULL) { 
    33. 32         return NULL; 
    34. 33     } 
    35. 34  
    36. 35     s = string; 
    37. 36     while (*s) { 
    38. 37         if (isupper(*s)) { 
    39. 38             *s = (char) tolower(*s); 
    40. 39         } 
    41. 40         s++; 
    42. 41     } 
    43. 42     *s = ''; 
    44. 43     return string; 
    45. 44 } 
    46. 45 */  
    47. 46   
    48. 47 void main()  
    49. 48 {  
    50. 49     char *test="ABCDEFGhijklmN";  
    51. 50     strlower(test);  
    52. 51     cout<<test<<endl;  
    53. 52 }  

    其中,如果采用char *test=”ABCDEFGhijklmN”;会产生运行时错误。Char test[]=”ABCDEFGhijklmN”则程序正常运行,原因如前所述。

    技术是一张窗户纸,一捅就破,come!
  • 相关阅读:
    spring基于xml导入配置文件
    spring中bean的继承和依赖关系
    spring整合junit
    spring新注解说明
    Web微信开发工具无法输入中文?官方bug
    vue踩坑 导出new Vue.Store首字母要大写
    关于vue ui组件
    vue组件的生命周期
    Vue的指令以及组件化开发
    webpack的npm扩展使用
  • 原文地址:https://www.cnblogs.com/adeng-x/p/6373568.html
Copyright © 2011-2022 走看看