C语言中字符串与字符数组的使用

引言:在C++中,对于字符串的操作,我们常使用 String 类,使用起来极其方便,所有常常会用到的对字符串的操作均已封装好。但是,在C中,字符串我们使用字符数组来实现,而且如果不搞清楚字符数组与字符串之间的关系,常常会出现一些无法解释的问题。笔者之前一直对两者之间的关系有所疑惑,最近查阅相关资料,终于搞清楚,现整理出来。虽然这个不算什么大问题,但是不彻底搞清楚就是觉得心里不爽~希望各位看官批评指正。




首先,在这里写下字符数组最简单的定义并初始化的方法:

      char str[10]={'H','e','l','l','o','!'};

在这里只需注意以下几点:

1.“Hello!”数组元素个数为6个,它的个数必须小于定义数组的数组大小即10。

2.其余已被申请但未被赋值的内存均被赋值为 '\0'(ASCII:0),也就是说现在str数组中内存赋值情况如下:

地址内容
str'H'
str+1'e'
str+2'l'
...'l'
...'o'
...'!'
str+6'\0'
str+7'\0'
str+8'\0'
str+9'\0'
3.'\0'与ASCII中 space 的区别:

ASCII中0~31为“非打印控制字符”,其中例如 0号对应的’\0‘ ,13号对应的回车键,将它们按字符的形式打印到屏幕上的时候均为“ ”,它和空格 “ ” 是有本质上的区别。空格对应的ASCII为32号,它属于“打印字符”,只不过空格在屏幕上的表现形式也为 “ ” ,与无法打印的非打印控制字符显示的效果一样罢了。’\0‘仅仅作为一个字符串结束标志存在着,它的作用就是一个标志




接下来,谈一下C语言中的字符串:

同样地,先写一下字符串最简单的声明定义方式,

1.  char str[]={"Hello World !"};

2.  char str[]="Hello World !";

以上两种方式等价。但是下面这种方式是错误的!

3.  char str[];

     str="Hello World !";

为什么第三种方式是错的呢?这就需要了解在执行前两种方式的语句时,计算机做了什么。首先当我们指明要赋的值为"Hello World !"时,计算机会在内存中开辟一个能够装下这个值的内存空间,这也就是为什么str[]的“[]”中不需要写一个具体数值的原因,需要多大计算机已经帮你算好。而如果我们采用第三种方式,会报这样的错:“storage size of 'str' isn't known” 意思就是大小不明。

但是如果想要在声明这个字符串时并不赋值的话,可以采用下面这种方式:

4.   char * str;

      str="Hello World !";

当然,更直接的方式:char *str="Hello World !"; 也是允许的。

那么,为什么第四种方式又是可行的呢?执行这条语句的时候,计算机同样为"Hello World !"开辟了一定大小内存空间,但是这条语句是将这个内存空间的首地址赋值给str指针,执行 char str[] 语句后,虽然str也是一个指针类型,但是任何数组名的那个指针都是一个常指针!!!!跟其他常量一样,它是不能再被赋值的!用以下方式可以证明:

     char *str="Hello World !";

     str++;

     printf("%c",*str);//结果输出为’e‘

而采用以下方式,直接报错。原因就是下面的str为常指针,不能被重新赋值,也就是str++;是错误的。

     char str[]="Hello World !";

     str++;

     printf("%c",*str);

但是第4种利用指针的写法也有它的局限性,以下面的代码为例:

     char *str="Hello!";

     str[0]=str[1];

     printf("%s",str);

执行以上代码时,程序会崩溃掉,而如果将第一句改为 char str[]="Hello!"; 程序就可以正常执行,其中的原因涉及到计算机内部存储器的工作方式。

(这部分转自http://blog.sina.com.cn/s/blog_8f99a1640101okxa.html)

使用 char *str 的情况下计算机操作的步骤:
计算机做的步骤:
1. 计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"Hello!")放到常量存储区,这部分存储器是只读的。

2. 程序在栈上创建 str 变量
栈是存储器中计算机用来保存局部变量的部分,局部变量也就是位于函数内部的变量,str 变量就在这个地方。

3. str 变量设为"Hello!"的地址
str 变量将会保存字符串字面值"Hello!"的地址。为了防止修改,字符串字面值通常保存在只读存储器中。

4. 计算机试图修改字符串
程序试图修改 str 变量指向的字符串中的内容时就会失败,因为字符串是只读的。


使用 char str[] 的情况下计算机操作的步骤:
1. 计算机加载字符串字面值:
当计算机把程序载入存储器时,会把所有常数值(如字符串常量"Hello!")放到常量存储区,这部分存储器是只读的。

2. 程序在栈上新建了一个数组
我们声明了数组,所以程序会创建一个足够大的数组来保存字符串"Hello!"

3. 程序初始化数组
除了为数组分配空间,程序还会把字符串字面值"Hello!"的内容复制到栈上。

所以,使用指针方式声明的字符串值无法改变。




最后补充一下刚刚提到的'\0'相关的问题。

     char str[]="Hello";

     char str1[]={'H','e','l','l','o'};

     printf("%d\n",sizeof(str));

     printf("%d\n",sizeof(str1));

结果:6   5

造成差异的原因就是str被以字符串的形式赋值,它内部的元素其实为 'H','e','l','l','o','\0' 共6个,而str1只是一个单纯的字符数组。

另外C语言中printf("%s",str);提供了按字符串形式输出的控制符号’%s‘,将以上的str和str1按这种方式输出。

     printf("%s\n",str);

     printf("%s\n",str1);

输出str1的时候可能会跟着一些乱码,原因就是以str1为首地址的接下来几块内存单元中没有'\0',虽然我们未使用的内存中的值应该为'\0',但是这并不一定。而另一种写法:char str[10]={'H','e','l','l','o'}; 它的输出结果中绝对不会夹杂乱码,因为未被赋值的内存会被计算机主动赋值为'\0',这也算是在设计上的巧妙。




以上就是我今天整理的一些C中字符串和字符数组的一些需要特别注意的点,欢迎各位批评指正~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值