char *p = "123"和char a[] = "123"根本就不同
2012-09-13 16:03
253 查看
示例代码如下:
#include <stdio.h>
int main(void)
{
char *p = "123"; //等价于char *p; p = "123";
char a[] = "123"; //等价于char a[] = {'1', '2', '3', '\0' };
printf("address a = %p, p = %p, &p = %p\n", a, p, &p);
a[2] = '4';
// p[2] = '5';
printf("a[2] = %c, p[2] = %c\n", a[2], p[2]); //a[2]等价于*(a+2),p[2]等价于*(p+2)
printf("\"abcd\"[1] = %c, \"abcd\" = %p, &\"abcd\"[2] = %p\n",
"abcd"[1], "abcd", &"abcd"[2]);
return 0;
}
1、两者的差别
代码中第5行的意思是声明一个字符指针变量p,然后给它赋值为字符串常量“123”的首地址(如示例中的0x8048590)。在C语言中,字符串都是以字符数组的形式存储的,而这里的字符串常量就是一个无名字符数组,由于没有数组名,所以一般通过指针变量获得它的首地址来间接地进行数据访问,如示例中,先通过指针变量p获得无名字符数组的首地址,然后通过第13行的p[2]来访问这个无名字符数组中的第3个元素(即字符’3’)。
注意:指针变量的存储空间(在32位机中为4个字节)只够存储一个地址值(在32位机中是一个4字节的无符号整数),这里不能错误地认为是把字符串常量“123”赋值给p或者*p。
字符串常量一般存储在可执行文件的只读数据段(section .rodata),不能对其中的元素进行修改,所以,把第11行的语句加入到程序中,执行时会产生段错误,尽管用编译器GCC可成功编译。
第6行的意思是声明一个字符数组并给它初始化为字符串“123”(字符串以空字符为结尾)。
注意:数组只有在初始化阶段才能同时为其中的多个元素赋值。
因此,5、6两行中的字符串“123”的含义是完全不同的:第5行中的“123”代表着它(无名字符数组)自身的首地址,而第6行的“123”仅仅是字符数组a的初始值
通过下面的图示更能直观地理解两者的差异(小端模式):
2、比较酷的用法
除了可以通过指针变量间接地访问无名字符数组的元素以外,也可以通过数组下标或指针的形式直接访问其中的元素,如”abcd”[1]或者*(“abcd” +1),它们获得的值都是字符’b’。
因为字符串常量代表它自身的首地址(如0x80485fa),而访问数组元素都是通过类似于“ *( 数组名(即首地址)+ sizeof(元素数据类型) x n(第n+1个元素) ) ”这样的形式进行访问的,所以”abcd”[1](等价于 *(“abcd” + 1) )的意思是从无名字符数组首地址加1的地址(即0x80485fb)中获得第2个元素的值(即字符’b’)。
例子结果输出:
address a = 0xbfdd0f78, p = 0x8048590, &p = 0xbfdd0f74
a[2] = 4, p[2] = 3
"abcd"[1] = b, "abcd" = 0x80485fa, &"abcd"[2] = 0x80485fc
尽管指针变量的值是一个32位的无符号整数,但在printf函数中,还是特别使用了另外的格式符%p来输出其中的值,说明指针变量是有它特有的数据类型的。虽然使用%x等格式符能正确地输出指针变量的值,但一般会警告数据类型不匹配。
注:此文章转自tanglinux的同名博客。
#include <stdio.h>
int main(void)
{
char *p = "123"; //等价于char *p; p = "123";
char a[] = "123"; //等价于char a[] = {'1', '2', '3', '\0' };
printf("address a = %p, p = %p, &p = %p\n", a, p, &p);
a[2] = '4';
// p[2] = '5';
printf("a[2] = %c, p[2] = %c\n", a[2], p[2]); //a[2]等价于*(a+2),p[2]等价于*(p+2)
printf("\"abcd\"[1] = %c, \"abcd\" = %p, &\"abcd\"[2] = %p\n",
"abcd"[1], "abcd", &"abcd"[2]);
return 0;
}
#include <stdio.h> int main(void) { char *p = "123"; //等价于char *p; p = "123"; char a[] = "123"; //等价于char a[] = {'1', '2', '3', '\0' }; printf("address a = %p, p = %p, &p = %p\n", a, p, &p); a[2] = '4'; // p[2] = '5'; printf("a[2] = %c, p[2] = %c\n", a[2], p[2]); //a[2]等价于*(a+2),p[2]等价于*(p+2) printf("\"abcd\"[1] = %c, \"abcd\" = %p, &\"abcd\"[2] = %p\n", "abcd"[1], "abcd", &"abcd"[2]); return 0; }
1、两者的差别
代码中第5行的意思是声明一个字符指针变量p,然后给它赋值为字符串常量“123”的首地址(如示例中的0x8048590)。在C语言中,字符串都是以字符数组的形式存储的,而这里的字符串常量就是一个无名字符数组,由于没有数组名,所以一般通过指针变量获得它的首地址来间接地进行数据访问,如示例中,先通过指针变量p获得无名字符数组的首地址,然后通过第13行的p[2]来访问这个无名字符数组中的第3个元素(即字符’3’)。
注意:指针变量的存储空间(在32位机中为4个字节)只够存储一个地址值(在32位机中是一个4字节的无符号整数),这里不能错误地认为是把字符串常量“123”赋值给p或者*p。
字符串常量一般存储在可执行文件的只读数据段(section .rodata),不能对其中的元素进行修改,所以,把第11行的语句加入到程序中,执行时会产生段错误,尽管用编译器GCC可成功编译。
第6行的意思是声明一个字符数组并给它初始化为字符串“123”(字符串以空字符为结尾)。
注意:数组只有在初始化阶段才能同时为其中的多个元素赋值。
因此,5、6两行中的字符串“123”的含义是完全不同的:第5行中的“123”代表着它(无名字符数组)自身的首地址,而第6行的“123”仅仅是字符数组a的初始值
通过下面的图示更能直观地理解两者的差异(小端模式):
2、比较酷的用法
除了可以通过指针变量间接地访问无名字符数组的元素以外,也可以通过数组下标或指针的形式直接访问其中的元素,如”abcd”[1]或者*(“abcd” +1),它们获得的值都是字符’b’。
因为字符串常量代表它自身的首地址(如0x80485fa),而访问数组元素都是通过类似于“ *( 数组名(即首地址)+ sizeof(元素数据类型) x n(第n+1个元素) ) ”这样的形式进行访问的,所以”abcd”[1](等价于 *(“abcd” + 1) )的意思是从无名字符数组首地址加1的地址(即0x80485fb)中获得第2个元素的值(即字符’b’)。
例子结果输出:
address a = 0xbfdd0f78, p = 0x8048590, &p = 0xbfdd0f74
a[2] = 4, p[2] = 3
"abcd"[1] = b, "abcd" = 0x80485fa, &"abcd"[2] = 0x80485fc
address a = 0xbfdd0f78, p = 0x8048590, &p = 0xbfdd0f74 a[2] = 4, p[2] = 3 "abcd"[1] = b, "abcd" = 0x80485fa, &"abcd"[2] = 0x80485fc
尽管指针变量的值是一个32位的无符号整数,但在printf函数中,还是特别使用了另外的格式符%p来输出其中的值,说明指针变量是有它特有的数据类型的。虽然使用%x等格式符能正确地输出指针变量的值,但一般会警告数据类型不匹配。
注:此文章转自tanglinux的同名博客。
相关文章推荐
- char *p = "123"和char a[] = "123"根本就不同
- char *p = "123"和char a[] = "123"根本就不同
- char *p = "123"和char a[] = "123"根本就不同 .
- char *p = "123"和char a[] = "123"根本就不同
- char * strArry[]={"123","456","789"};
- char *p="abc"与char p[]="abc"的不同
- char* a = "zhf"; 和 char a[] = "zhf"; 之间的区别
- char a[] = "hello world1"和char *p = "hello world2";的区别
- 立此存照(17)[C++]error C2040: "s":"std::string"与"char [21]"的间接寻址级别不同
- vs2005和gcc对于char a[] = "hello!";的不同处理
- 论printf("123");while(1);在不同平台下的不同输出
- char a[] = "hello world1"和char *p = "hello world2";的区别
- 从语句 char* p="test" 说起
- IntelliSense: "const char *" 类型的实参与 "LPCTSTR" 类型的形参不兼容 (vs2012)
- 主题:Invalid char "/357" in expression
- 字符串赋值给字符指针(char *a="hello")的正确理解方式
- 不会因不同浏览器区别IE6,IE7让布局崩溃的弹出"确认"对话框
- warning: deprecated conversion from string constant to "char *"
- 关于String a="123"和String a=new String("123")