字符串赋值给字符指针变量

Posted on 2018-07-02 12:12  黑企鹅  阅读(1161)  评论(0编辑  收藏  举报

char *p,a='5';

p=&a;                     //显然是正确的,
p="abcd";              //但为什么也可以这样赋值??

双引号做了3件事:  
1.申请了空间(在常量区),存放了字符串 
2. 在字符串尾加上了'/0'    
3.返回地址

这里就是 返回的地址  赋值给了  p                      

char *p = “hello”;

把p换成数组,然后再赋值就不行

字符串常量"hello"出现在一个表达式中时,"hello"表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。

所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组。 

char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的

如果写成char a[10]

然后 a = “hello” 这样就错误了。  

同样是a数组,char a[10] = “hello”;这种是数组的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一个道理

但是换成char a [10]

然后a = “hello”就不行了 “hello”赋值的值是一个地址,而a虽然也有地址,但是这与指针是不一样

的,指针的值是地址,而数组的值虽然也是地址,但是却是一个常量,所以不能给常量赋值。

 

以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写
"abc",那么编译器帮你存储的是"abc\0"

 

"abc"是常量吗?有时是,有时不是。

不是常量的情况:"abc"作为字符数组初始值的时候就不是,如

char str[] = "abc";
因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为
字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
char str[3] = {'a','b','c'};
又根据上面的总结1,所以char str[] = "abc";的最终结果是
char str[4] = {'a','b','c','\0'};
做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里
的"abc\0"因为不是常量,所以应该被放在栈上。

是常量的情况: 把"abc"赋给一个字符指针变量时,如
char* ptr = "abc";
因为定义的是一个普通字符指针,并没有定义空间来存放"abc",所以编译器得帮我们
找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器
最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译
通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序
常量区中的东西。
如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被放在常量区中,
但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,只不过是它
所指向的东西被放在常量区罢了。

 

数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],
也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。

 

对于char str[] = "abcdef";就有sizeof(str) == 7,因为str的类型是char[7],
也有sizeof("abcdef") == 7,因为"abcdef"的类型是const char[7]。
对于char *ptr = "abcdef";就有sizeof(ptr) == 4,因为ptr的类型是char*。
对于char str2[10] = "abcdef";就有sizeof(str2) == 10,

因为str2的类型是char[10]。
对于void func(char sa[100],int ia[20],char *p);就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,
因为sa的类型是char*, ia的类型是int*,p的类型是char*。

 

 

char *s1=“string1”;//定义字符串常量,指针形式

char s2[]=“string2”;//定义字符串常量,数组形式

char *s3=new char[10];//定义字符串变量并分配内存 指针形式

strcpy(s3,"string3");//为s3赋值

char s4[10];//定义字符串变量,数组形式

strcpy(s4,"string4");//为s4赋值

以上方法都能定义一个字符串,同时通过字符串在内存中的分布可以清楚地知道是什么情况

C语言中字符串赋值方法strcpy(char*d,char*s)其中s代表是源字符串,d代表目标字符串,也就是要赋值的字符串。

 

在c语言中,比如char *p,其中p是一个指针,p中存储一个内存缓冲区的首地址。所谓的内存缓冲区就是一段
连续的内存地址,里面存放了一系列的字符。那系统又是如何判断在哪里结束呢。那就是根据符号‘\0’。这个
字符占一个字节,8位,每位的值都是0。