注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

饥民2011

一直在搬砖

 
 
 

日志

 
 
 
 

C 语言里的字符串---字符数组  

2013-02-19 00:50:23|  分类: c/c++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
//////      实际上, c中并没有字符串这种数据类型,  也就是说c是没有像java, .net等其他高级语言中常用的String类型.
     
      首先要强调:
      a. c语言有无字符串?         有!
      b. c语言有无字符串类型    无!
      c. c语言字符串是否就是不是字符数组   是!
      b. c语言字符串和字符数组是同一样东西?   不是!

     实际上,  c语言中, 字符串是1个特殊的字符数组,  特殊在什么地方? 就是字符数组最后1个元素可以是任意字符, 而字符串(属于字符数组的最后1个元素是'\000',

      也就是说, c

1.字符类型

char 就是c的字符类型
定义1个字符变量,跟住赋值.
char a;
a='a';   //这里只能用单引号,  双引号只能用于字符数组.

打印这个字符:
printf("char a is %c",a)
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 
2.字符数组
   由名字得知, 字符数组实际上是1个数组,其性质与数字型数组其实很类似的, 但是也有一些区别.

定义1个字符数组:
char c[5];  //:定义1个长度为5的字符数组,  也就是有5个字符元素啦
char c[];   // 错误,定义1个数组同时必须指定它的长度
赋值:

c[0]='a';c[1]='b';c[2]='c';c[3]='d';c[4]='e';    //正确
c ="abcde";     //错误
c={'a','b','c','d','e'}; //错误 因为c数组定义时已经设定了长度5, 而数组的长度一旦定义就不会改变, 所以c认为这种赋值不合法,因为有机会改变字符数组c的长度.

例子:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
执行结果:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011

可以见到, 字符数组定义后, 赋值相当麻烦啊.  而且不像数字型赋值, 不方便循环赋值..
所以一般在定义1个字符数组语句同时执行赋值:
char c[]={'a','b','c','d','e'}  //  正确
这样的话, 字符数组c在定义的同时它的各个元素和长度也被定义为5了.

char c[5]={'a','b','c','d','e'} //正确
char c[4]= {'a','b','c','d','e'}  //错误, 制定长度为4, 但是赋予5个元素
char c[7]={'a','b','c','d','e'} //正确, 但是c[5]和c[6]这两个元素都被设为NULL '\000'  注意不是'0'啊

例子:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 
执行结果:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
可以见到d的长度是6, 但是d[5]的值显示不出来,  因为上面已经提过, 如果赋值的元素个数少于数组长度, 后面的元素会自动被赋值成'\0', 而'\0'是个空字符.

debug一下就可以看清楚了:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 
而这时字符数组d就是1个字符串了, 因为他是以'\000'结尾的字符数组啊!



3.字符
     上面都提过很多次了,  字符串是以'\000' 结尾的字符数组.

     定义1个字符串:
     char c[]={'c','d','e','f','d','g','\000'}; // 长度为7
     而实际上还可以这样定义:
     char c[]="cdefdg"  // 系统会自动补1个Null字符'\000'到这个字符串的最后1个元素, 长度也是7
     char c[7]="cdefdg" //正确  这个是最常用的字符串变量赋值方法.

     char c[6]="cdefdg"  //这个不是字符串, 长度不足以容纳最后1个NULL字符'\000'
    
看个例子:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 
 
 执行结果:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 

 

上面c 于d都是字符串, 因为他们都是'\000'结尾的, 而e是1个普通的字符数组:
函数sizeof返回的是数组长度, 它会将'\000'计算在内
而函数strlen返回的是字符串长度, 它不会计算'\000'在内  <string.h>

所以对于字符串来讲 sizeof(d) =7 它有7个元素嘛,  但是strlen长度只有6
而对于一般字符串(没有'\000'字符, sizeof 和 strlen 返回的结果是一样的)

现在我修改一下这个函数, 令
字符串c的第4个字符c[4]='\000':
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 

执行结果:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011
 
可以见到 字符串c 居然显示3个字符"cde", 了 strlen长度也只有3
因为printf 函数 和strlen函数一样, 都会从字符数组的头1个元素往后面遍历, 当遇到'\000'时,就会认为这是1个字符串, 而且会在这里结束.


4. 一些指针的意思:

         定义1个字符串:
         char c[]="abcdef"; //
         这样c就是1个长度为7的字符数组(也是字符串)c,c的元素包括 'a','b','c','d','e','f','\000', 上面已经解析过了.

         而实际上, 跟int类型的数组名一样, 这里的字符串(也是字符数组)名字c本身就是1个字符型指针,  它指向数组c的一个的元素c[0]的地址.
         也就是讲:
         *c == c[0] = 'a'
         *(c+1) = c[1] = 'b'
         *(c+i) = c(i)   //这个是经典公式啊.

   也可以定义1个字符型指针*p
         char *p;
  
    给p赋值:
    p=c;   //因为数组名c也是指针啊, 所以不需要取址符&,  p=&c;是错误的!

    这样, p与c就是等价的(指向同1个地址
    *p == c[0] = 'a' = p[0]
    *(c+1) = c[1] = 'b' = p[1]
    *(p+i) = p(i)=c(i)   //这个是经典公式啊.


有另1个种定义数组的方法:
       char *q = "abcdef"  ,
       这样指针q也是只向1个字符串. 用法跟上面指针p差不多

例子:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011

输出:
C 语言里的字符串---字符数组 - 饥民 - 饥民2011

可以见到:
1. 用数组c的长度是7(sizeof(c)), 而字符串长度是6(strlen).
    而用指针p去只想数组c, 求sizeof(p) 是多了1个元素的, 尾部多1个'\000',就是两个'\000'结尾啦, 但是字符串长度是一样的.

2. 可以见到 sizeof 和 strlen的参数实际上都是指针(c和p和q)都是指针.
所以在c语言中, 有很多函数的参数实际上都是指针, 这就是用地址传递产生了
例如
int strlen(char* p){     //这里char* p表示p是1个字符型参数,  而定义1个字符串p使用char *p;的 注意区别~

}


见到输出, p与q的部分是完全一样的,
是否p与q的用法就完全一样呢?

不是的
首先我定义字符串c时:
char c[]="abcdef" 

这个c是1个字符串变量
 
那么p=c;  p就指向1个字符串变量了

执行
p[1] = 'k';
p[2] ='h';  //都是合法的, 因为变量的值可以改变嘛

而定义1个字符指针q
char *p="abcdef"; 时

首先系统会定义1个字符串常量"abcdef",
然后指针p指向这个常量.

执行
q[1]='k'; 是不合法的, 因为常量的值不能修改, 所以里面的元素的值也不允许的修改的.

所以要定义1个字符串, 而且打算修改时 不要用
 char *p="abcdef"; 

这种方式, 但是用于常量时就推荐这种~
        

 
   
    

 
 


 
  评论这张
 
阅读(352)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017