C语言中的数组和指针以及字符串

  数组名同时也是该数组首元素的地址,而指针提供了一种用来使用地址的符号方法,因此指针能够很有效地处理数组。

  将一个整数加给指针,这个整数会和指针所指类型的字节数相乘,然后所得的结果会加到初始地址上

date +  == &date[];        // 相同的地址
*(date + ) == date[]; // 相同的值

  在函数原型或函数定义头的场合中(并且也只有在这两种场合中),可以用int ar[]代替int* ar,处理数组的函数实际上是使用指针做为参数的

int sum(int* ar, int n);
int sum(int ar[], int n); // 二者在此处等价

  无论在任何情况下,形式int* ar都表示ar是指向int的指针。形式int ar[]也可以表示ar是指向int的指针,但只是在声明形式参量时才可以这样使用。使用第二种形式可以提醒读者ar不仅指向一个int数值,而且它指向的这个int是一个数组中的元素。

C语言中的字符串

  字符串是C里面最有用、最重要的数据类型之一。C语言中的字符串是以空字符('\0')结尾的char数组。

  下面两个都声明str是一个指向给定字符串常量的指针:

char str[] = "Klingon";
const char* str = "Klingon";

  在两种情况下,都是被引用的字符串本身决定了为字符串预留的存储空间大小。尽管如此,这两种形式并不完全相同。

  数组形式(str[])在计算机内存中被分配一个有8个元素的数组(其中每个元素对应一个字符,还有一个附加的元素对应结束的空字符'\0'),每个元素都被初始化为相应的字符。通常,被引用的字符串存储在可执行文件的数据段部分;当程序被加载到内存中时,字符串也被加载到内存中,位于静态存储区;在程序开始运行后才为数组分配存储空间,这时候把被引用的字符串复制到数组中。

  指针形式(* str)也在静态存储区为字符串预留8个元素的空间。一旦程序开始运行,还要为指针变量str另外预留一个存储位置,以在该指针变量中存储字符串的地址,指针变量str初始时指向字符串的第一个字符。

  总之,数组初始化是从静态存储区把一个字符串复制给数组,而指针初始化只是复制字符串的地址。

char* str = "Klingon";
str[] = 'F'; // 是否允许?

  

  您的编译器可能会允许上面的情况,但按照当前的C标准,编译器不应该允许这样做。这种语句可能会导致内存访问错误。原因在于编译器可能选择内存中的同一个单个的拷贝,来表示所有相同的字符串常量。代码如下:

char* str = "Klingon";
str[] = 'F'; // ok?
printf("Klingon");
printf(":Beware the %ss!\n","Klingon");

  

  如果编译器使用这种单个拷贝表示法并且允许把str[0]改为'F'的话,那将会影响到所有对这个字符串的使用。于是打印字符串"Klingon"的语句实际将会显示"Flingon",上述代码运行结果如下:

Flingon:Beware the Flingons!

  

  实际上,有些个编译器确实是按这种容易混淆的方式工作,而其他的一些则会产生程序异常中断(如Microsoft Visual Studio)

  因此,建议的做法是初始化一个指向字符串常量的指针时使用const修饰符:

const char* str = "Klingon";    // 推荐用法

  而用一个字符串常量来初始化一个非const的数组,则不会导致此类问题,因为数组从最初的字符串得到了一个拷贝

char str[] = "Klingon";
str[] = 'F'; // 合法
上一篇:JSon_零基础_001_将布尔类型数组转换为JSon格式字符串,返回给界面


下一篇:Java将一段逗号分割的字符串转换成一个数组