在我们学习的过程中,在定义字符串时常常会用char* 或者 char[]去定义一个字符串,可是这两个的区别却天差地别。
今天在这里我阐述一下自己对这两种定义的理解与看法。
首先分别用这两种方法定义字符串,如下。
char *str1 = "abcd1234";
char str2[] = "abcd1234";
接下来,我们分别对这两种方法定义的字符串进行测试。
printf("%d %d\n",str1,str2);

显而易见,这两种定义的方法在strlen的作用下的值是一样的,其字符串的长度并无差别。
再进行下面的测试。
char *str1 = "abcd1234";
char *str2 = "abcd1234";
char str3[] = "abcd1234";
char str4[] = "abcd1234";
printf("%p %p\n",str1,str2);
printf("%p %p\n",str3,str4);
如果这样运行的话,结果会是什么呢?

这是为什么呢?用char * 定义的两个内容一样的字符串的地址竟然是一样的,而char [] 这样定义的内容相同的字符串却不一样?
我们接下来继续看。
char *str1 = "abcd1234";
char str2[20] = "abcd1234";
strncat(str1,str2,4);
printf("%s\n",str1);
用strncpy来进行测试,意思为将str2的前四个字节的内容复制到str1中。我们来看看结果如何。

我们发现,程序直接崩溃掉了。如果这样来呢?
char *str1 = "abcd1234";
char str2[20] = "abcd1234";
strncpy(str2,str1,4);
printf("%s\n",str2);

此时,却可以正常的使用。那么之前的那些是什么原因导致的呢?
经过分析以及自己的理解,char str[]这里单独的str表示的是一个char类型的数组指针,该指针所指向的数组内容是保存在栈上面的,是可以修改的。而char *str是一个字符串指针,这个指针指向的是字符串第一个字符的地址,而这个指针存在栈上,但是字符串的内容并不在栈里面,而在字符常量区域里面储存。所以查看char *str1 = "abcd1234"与char *str2 = "abcd1234"的地址时,他们都是储存的字符a的地址,所以这个地址时相同的,所以其 %p 的值也是一样的,但是char str3[] = "abcd1234" 与 char str[] = "abcd1234"是分别两个char类型的数组,而str3与str4分别表示的是char型的数组指针,所以他们的地址时不同的。
char *str1 = "abcd1234";
char str2[20] = "abcd1234";
strncat(str1,str2,4);
当我们测试以上代码时,由于在栈里面存储的仅有字符的地址,所以当进行字符串拼接时,首先在栈里面找不到str1中的"abcd1234"而这时的字符串在字符常量区,是无法修改的,所以出现了程序崩溃,报错。
char *str1 = "abcd1234";
char str2[20] = "abcd1234";
strncpy(str2,str1,4);
printf("%s\n",str2);
而当我们测试上面的代码时,如果数组一样,利用指针的访问,是可以轻而易举的改变、修改、拼接str2,所以可以进行strncat的执行。
本人愚见,欢迎大家共同探讨研究,如果错误,请及时联系作者进行修改更正,谢谢大家!