字符串常量余字符串指针的认识
最近遇到字符串常量与字符串指针的各种问题,下面一一解决
一 关于他们地址的问题
有一篇文章《c语言中字符数组与字符串指针》写得很好下面贴出来,并且加上我自己的理解 这是其中举例的代码,并作适当修改来理解。
#include <stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{
char day[15] = "abcdefghijklmn";
char* strTmp = "opqrstuvwxyz";
printf("&day is %x\n", &day);
printf("&day[0] is %x\n", &day[0]);
printf("day is %x\n", day);
printf("\n&strTmp is %x\n", &strTmp);
printf("&strTmp[0] is %x\n", &strTmp[0]);
printf("strTmp is %x\n", strTmp);
printf("strTmp is %d\n", strlen(strTmp));
printf("strtmp is %d\n", sizeof(strTmp));
printf("*strtmp is %d\n", sizeof(*strTmp));
printf("DAY is %d\n", strlen(day));
printf("DAY is %d\n", sizeof(day));
getchar();
return 0;
}
运行结果如图显示
在所举例的文章中对代码的理解为
一下为文章内容中的解释
”
先看看前三个输出也就是关于变量day的,在 char day[15] = "abcdefghijklmn"; 这个语句执行的时候,系统就分配了一段长15的内存,并把这段内存起名为day,里面的值为"abcdefghijklmn",如下图所示:
再看程序,第一个输出,&day,&号是地址运算符,也就是day这个变量的内存地址,很明显,在最前面,也就是a字符所在字节的地址;
对于第二个输出也就好理解了,&day[0],就是day数组中第一个变量(也就是a)的地址,因此他们两个是一样的;
第三个输出是day,对于数组变量,可以使用变量名来索引变量中的内容,其实这里的day可以理解成数组变量退化的指针,并且指向数组的开头,既然把它理解成指针,那么它的值肯定是地址了,所以他的值和上面两个也一样。
再看看后面三个输出,关于字符串指针strTmp,在执行char* strTmp = "opqrstuvwxyz";后,内存的图示如下:
如图所示,内存分配了两段内存,一个名为strTmp,类型是一个字符指针,另外一段是一个字符串常量,且strTmp里面存放着字符常量的首地址,注意这里无法通过strTmp修改这段字符串,因为是常量;于是程序中的后面三个输出就好理解了;
&strTmp:strTmp这个字符指针的地址
&strTmp[0]:strTmp所指字符常量第一个字符的地址
strTmp:strTmp这个字符指针的值,即字符常量的首地址
因此,最后两个的值是一样的。
指针可以这样理解,指针这种类型,和int,char,double等等是一样的,只是它用来保存地址值的,而int变量保存整数,char变量保存字符,仅此而已,就char型指针或者int指针,本质是一样的,都是存放的地址,只不过那个地址所里面的变量类型不同而已,还有一种void型指针,就是可以放任何类型变量的地址。“
在《c primer plus》第五版中,285页,”当程序执行的时候,还要为指针变量另外预留一个存储位置,以在指针变量中存储字符串的地址“ 也符合上 文中的解释,
二 为何可以对字符串指针求strlen,strTmp不应该是个指针变量吗,不应该是一个地址吗,即便可以,不是指向第一个元素吗,求strlen不应该时1吗
char* strTmp = "opqrstuvwxyz";
第一次*只是声明,在执行这一句的时候已经在静态区为字符串预留了x个元素空间,并且求这个的字符串长度,肯定是strlen(strTmp),strTmp是个字符串指针,他的值是
opqrstuvwxyz,所以可以printf("strtmp is %s\n", strTmp);而* strTmp才是指向第一个元素的,printf("strtmp is %c\n", *strTmp);输出o,而
printf("strtmp is %c\n", strlen(*strTmp))就是错的,不是字符串,也没有\0.
百度百科里写有
函数原型 extern unsigned int strlen(char *s);内部变量就是一个字符串指针,直到遇到\0就停止,
char Array[3] = {'0'};
sizeof(Array) == 3;
char *p = Array;
strlen(p) == 1;//sizeof(p)结果为4
在传递一个数组名到一个函数中时,它会完全退化为一个指针