小议char *和C语言的字符串
作者:乾坤一笑
来源:
摘要:介绍了C语言中的char *和字符串,比较深入
前几天和清风雨交谈strncpy()函数的时候,他认为“如果一个函数有一个char * str的参数,那么str一定是一个字符串”,而我对此不以为然。难得到了周末,抽得出功夫,谈谈我对char *含义的认识,与大家共同讨论一下。
C语言是开发操作系统的首选语言,在很多方面都能从C代码中看到机器的固有性质。比如,PASCAL语言的数组索引是从1开始计数,而C语言就是从0开始计数。从0开始计数不太符合一般人的正常思维模式,但是为什么C语言要采用这种设计方式呢?因为C语言最初主要是为操作系统开发人员和编译器设计人员设计的——对于经常需要考察内存地址的开发人员,偏移量的概念在他们脑子里面根深蒂固。要把100个int型的整数放在从地址0x0000开始的一段内存中,如果系统是按Byte编址的,那么第100个元素(其数组索引为99)的要放入的地址必然是:0x0000 + sizeof(int) * 99, 而不是乘以100,所以索引以0开始是很有好处的。(C语言的底层特性请参考P.V.D.L的《Expert C Programming——Deep C Secrets》,中文版《C专家编程》)
同样而言,C语言对所谓字符串的处理也和其他语言不同。(参见拙著《我用错了strcat() 》文后的评论) 它同样体现了便于系统设计的特点。例如unix系统总是把设备都映射为文件,对I/O流、光驱、硬盘、modem的访问最终都转换为了对文件的处理。而文件,也可以看作是一个长长的字符数组(文件以EOF结尾)。C语言没有专门定义字符串数据类型(如其他语言中的string),它用以'\0'结尾的字符数组来表示一个逻辑意义上的字符串。C语言用一些对于字符数组的处理函数(特别是对以'\0'结尾的字符数组的处理函数)来处理所谓的以'\0'结尾的字符串,并把他们放在string.*、stdio.*等一些标准库文件中。string这个字眼也就对人造成了某些误解,好像是C语言中定义了字符串这种类型一样。其实C语言只定义了char、int、float、void、poiner这几种基本类型,这正是C语言简洁之处。至于所谓的字符串,只是对字符数组的一种特殊应用而已。
由于没有了“字符串类型”,“传char *参数就是传一个字符串进来”之说自然也不攻自破。那么char *真正的含义是什么?我们不妨用大家最熟悉的int来对比一下。
#include <stdio.h>
int main(int argc, char *argv[])
{
int b[3] = { 17, 18, 19 };
int a = 5;
int d = 2103157716;
int * i; // pay attention to this variable
i = b;
printf("%d \n", *i); // i points to a array, *i gets the first number of the array,
// *i does not get the all elements of the array.
i = b + 1; // okey, i can get whichever element of the array.
printf("%d \n", *i);
printf("Int size: %d \n", sizeof(int));
printf("Address0: %#x \n", i); // if i++, the value of i add by sizeof(int)
i++;
printf("Address1: %#x \n", i);
i = &a; // i also can point to a int variable. as i is a pointer, we shoule
printf("%d \n", *i); // use & to get the address of a.
printf("%#x \n", d); // I use a big number to prove that int * is only a pointer,
i = &d; // which is not tig
- 最新文章
- 高端技术:椭圆曲线密码体制与电子政务[02-20]
- 外企面试官最爱提的问题TOP10[02-20]
- 面试:最易被忽略的12种高级错误[02-20]
- 2005年华为招聘--C语言笔试试题[02-20]
- 如何在网页中嵌入Media player 播放流媒体文件[02-20]
- 101件 Mozilla 浏览器能而 IE 不能做的事[02-20]
- 相关文章
