字符串指针与字符数组的区别

字符串指针与字符数组的区别


数组和指针都可以在它们的定义中用字符串常量进行初始化,尽管看上去一样,底层的实现机制却不相同。

定义指针时,编译器并不为指针所指向的对象分配空间,它只是分配指针本身的空间。
例如:下面的定义创建了一个字符串常量(为其分配了内存):

       char *p=”abcdefg”;      //”abcdefg”存储在静态常量区,p指向该”abcdefg”,即是p保存的是”abcdefg”在常量区的地址。

       注意只有对字符串常量才是如此,不能指望为浮点数之类的常量分配空间,如:

       Float *p=3.14;

由字符串常量初始化的数组是可以修改的。其中的单个字符在以后可以改变。

例如:
#include <stdio.h>

void fun(char *p)
{
        printf("-----%p\n",p);
        p[0]='s';
        puts(p);
}
int main()
{

        char a[]="123";
        char *p="123";
        char *q="123";

        printf("a===%p\n",a);     //a===0xbfdda00c     %p表示输出a的地址
        printf("p===%p\n",p);     //p===0x8048839
        printf("q===%p\n",q);     //q===0x8048839

       // fun("hello");           //-----0x8048855      // p[0]='s';错误 说明存储在静态常量区
       // fun(a);                 //-----0xbfdda00c     // 输出:s12  说明存储在栈中
        fun(p);                   //-----0x8048839      // p[0]='s';错误 说明存储在静态常量区

        return 0;
}

综上所述:
<1> 初始化的字符串数组存储在栈中,可以改变其值。
<2> 初始化的字符串常量指针存储在静态常量区,不能修改其值。
<3> 字符串作为实参传递存储在静态常量区。
<4> 程序段和代码段的起始地址0x08048000.

====================================================================================

数组要么在静态存储区被创建(如全局数组,指针数组),要么在栈上被创建(字符串数组)。指针可以随时指向任意类型的内存块。

(1) 修改内容上的差别
    char a[] = "hello";
    a[0]     = 'X';
    char *p- = "world"; //注意p指向常量字符串
    p[0]     = 'X';     //编译器不能发现该错误,运行时错误

(2) 用运算符sizeof可以计算出数组的容量(字节数)。sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

    char a[] = "hello world";
    char *p = a;
    printf("%d ",sizeof(a));      //12字节
    printf("%d ",sizeof(p));      //4字节

    计算数组和指针的内存容量
    void func(char a[100]) {
         printf("%d ",sizeof(a));   //4字节而不是100字节 说明函数的数组参数都是看做指针
    }

sizeof  指针 数组
-------------------------------------------
char p[];   // 编译不过
char p[0];  // sizeof(p) = 0
char p[8];  // sizeof(p) = 8
char * p = malloc (10);  // sizeof(p) = 4
用运算符sizeof可以计算出数组的容量(字节数),但是计算不出指针指向空间的容量,只能计算出指针变量的空间容量(4字节)

指针就是指针,成不了数组

----------------------------------------------
在C语言中,我们没有办法可以将一个数组作为函数参数直接传递。如果我们使用数组名作为参数,那么数组名会立即被转换为指向该数组第1个元素的指针。例如,下面的语句:
char hello[] = "hello";
声明了hello是一个字符数组。如果将该数组作为参数传递给一个函数,
printf ("%s\n", hello);
实际上与将该数组第1个元素的地址作为参数传递给函数的作用完全等效,即:
printf ("%s\n", &hello[0]);
因此,将数组作为函数参数毫无意义。所以,C语言中会自动地将作为参数的数组声明转换为相应的指针声明。也就是说,像这样的写法:
int strlen (char s[])
{
    ...
}

与下面的写法完全相同:
int strlen (char *s)
{
    ...
}

 


尊重作者,请转明来处:追Dream梦http://blog.csdn.net/pzhsunxu/article/details/7798365

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值