1 数组的特例:字符串
在C语言中,定义一个字符串样式的数组,有如下两种方式:
char arr[] = "abcdefg";
char *str = "abcdefg";
这两种方式有什么区别呢?别看它们表面上都差不多,其实差远了!
1.1 字符数组定义字符串——从一而终
这里的数组名 arr:实际上是个变种的“指针常量”,
(1)常量说明了“绑定关系”不能变,这种定义字符串的方式,会在栈帧里面存放“abcdefg\0”这一个字符数组实体,arr 在函数体的整个生命周期里面不能再绑定其他的东西!直到这个函数体的消亡,一起被销毁;
(2)“变种”有3个含义:
① 共享房子的大小:arr的大小,将等于"abcdefg\0"的大小
② 共享房子的位置:arr的地址,将等于战阵中"abcdefg\0"的首地址
③ 相敬如宾:arr这个指针不能随便去"abcdefg\0"里面随便乱指,只能通过arr[0],arr[1]……这种固定的方式去访问“abcdefg\0”中的内容
1.2 字符指针定义字符串——登徒浪子
这里的指针 char *str:是一个指针变量,它就是一个登徒浪子!
(1)变量说明了“绑定关系”可以随时变!str在整个函数体的生命周期中,不一定非要绑定"abcdefg\0"这一个字符串常量,看它不顺眼了,可以改!
(2)“登徒浪子”是相对独立自主的!
① str 拥有自己独立的大小(就是指针的大小,与机器字长有关),而与字符串常量"abcdefg\0"的大小无关;
② str 拥有自己独立的地址,在栈帧之中占据一席地位,独立地分配了栈帧中的字节!
③ str 特别喜欢指指点点,可以使用str++, str–这样的方式,在 “abcdefg\0” 里面指来指去!
1.3 测试代码
#include <stdio.h>
int main(int argc, char *argv[]){
char arr[] = "abcdefh";
char *str = "abcdefh";
printf("argv = 0x%x\r\n", &argv);
printf("argc = 0x%x\r\n", &argc);
printf("adress of arr = 0x%x\r\n", &arr);
printf("adress of char *str = 0x%x\r\n", &str);
printf("adress of arr[0] = 0x%x\r\n", &arr[0]);
printf("adress of str[0] = 0x%x\r\n", &str[0]);
printf("adress of str[1] = 0x%x\r\n", &str[1]);
printf("arr[1] = \'%c\'\r\n", *(arr + 1));
printf("arr[0] = \'%c\'\r\n", *arr);
printf("*str++ = \'%c\'\r\n", *str++);
printf("now, \"str\" points to = \'%c\'\r\n", *str);