字符串数组与字符串指针

我们可以用字符数组或者字符指针来保存字符串,那么这两个有什么区别呢?

  • 需要从内存角度来分析
#include <stdio.h>
int main()
{
    char str[] = "hello world!\n";
    // 直接输出字符串
    printf("%s", str);
    // 每次输出一个字符
    for (int i = 0; i < strlen(str); i++)
    {
        printf("%c", str[i]);
    }
    return 0;
}
#include <stdio.h>
#include <string.h>

int main()
{
    char *str = "hello world\n";
    
    // 直接输出字符串
    printf("%s", str);

    int i;
    int len = strlen(str);
    
    // 使用*(str+i)
    for (i = 0; i < len; i++)
    {
        printf("%c", *(str + i));
    }
    
    // 使用str[i]
    for (i = 0; i < len; i++)
    {
        printf("%c", str[i]);
    }
    
    return 0;
}
  • 这一切看起来和字符数组是多么地相似,它们都可以使用%s输出整个字符串,都可以使用 * 或 [ ] 获取单个字符
  • 区别:
    • 内存中的存储区域不一样,字符数组存储在全局数据区或栈区,字符指针的字符串存储在常量区。全局数据区和栈区的字符串有读取和写入的权限,而常量区的字符串只有读取权限,没有写入权限
#include <stdio.h>
int main()
{
    char arr[] = "abc";
    printf("%s\n", arr);
    arr[0] = 'b';
    printf("%s\n", arr);

    char *p = "abc";
    printf("%s\n", p);
    *p = 'b'; // Segmentation fault (core dumped)
    printf("%s\n", p);
}
  • 比较地址值
#include <stdio.h>
int main()
{
    char s1[] = "abc";                // “abc”是来自.rodata的副本,这条语句让“abc” 这个字符串在内存中有两份拷贝
                                      // 一份放在动态分配的栈里,一份放在.rodata里。
    char s2[] = "abc";                // “abc”是来自.rodata的副本。
    printf("s1==s2? %d\n", s1 == s2); // s1==s2? 0  说明s1不等于s2,s1==s2比较的是首元素的地址
    char *p1 = "abc";                 // p1 指向的是.rodata中“abc”的地址
    char *p2 = "abc";                 // p2 指向的是.rodata中“abc”的地址
    printf("p1==p2? %d\n", p1 == p2); // p1==p2? 1  p1==p2比较的是p1和p2指针变量存的地址值
    return 0;
}

例: 

#include <stdio.h>
char *str()
{
    // char *p ="hello";
    static char p[] = "hello"; // 随着函数str出栈而消亡,如果加上static 则把p放在了.data里,不会随着str函数出栈而消亡
    return p;
}
int main()
{
    char *q = NULL;
    q = str();
    printf("%s\n", q); // Segmentation fault (core dumped)

    return 0;
}
  • 在编程过程中如果只涉及到对字符串的读取,那么字符数组和字符串常量都能够满足要求;如果有写入(修改)操作,那么只能使用字符数组,不能使用字符串常量
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cam_______

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值