C 语言字符串用数组和指针初始化为什么会有这样的区别?-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

C 语言字符串用数组和指针初始化为什么会有这样的区别?

a123456678 2016-06-08 21:02:04 1615

直接用数组初始化:

#include <stdio.h>

int main(void) {
  char str[] = "abc";
  int i = 0;
  while (str[i] != '\0') {
    printf("%c\n", str[i]);
    i++;
  }

  str[1] = 'd';

  return 0;
}
没有问题,正常输出,没有报错。

但是如果用指针初始化:

#include <stdio.h>

int main(void) {
  char *str = "abc";
  int i = 0;
  while (str[i] != '\0') {
    printf("%c\n", str[i]);
    i++;
  }

  str[1] = 'd';

  return 0;
}

它执行到 str[1] = 'd' 的时候,就会报 segmentation fault,我在网上搜了一下,
都是说通过指针初始化的字符串是个常量,不能改变。感觉这个很坑啊,只是 char str[] = "abc" 和 char *str = "abc"; 这样小的区别而已,为什么通过指针初始化的那个就要是常量呢?是 C 语言规定就是这样,还是是可以理解的?

C语言
分享到
取消 提交回答
全部回答(5)
  • 游客x4uu57rrcwjuo
    2020-03-19 10:54:31

    编译器就是这么做的,记住就行了,不必太纠结。 对linux来说,程序加载后内存是分段的。 screenshot

    0 0
  • 一生有你llx
    2019-07-17 19:32:45

    编译器就是这么做的,记住就行了,不必太纠结。
    对linux来说,程序加载后内存是分段的。
    screenshot

    验证:

    include
    int main(){

    char a[]="abc";
    char b[]="abc";

    char *c="abc";
    char *d="abc";

    printf("%pn", a);
    printf("%pn", b);
    printf("%pn", c);
    printf("%pn", d);
    }
    结果:

    @ ➜ ~ ./a.out
    0x7fff52ac3afc
    0x7fff52ac3af8
    0x10d13cf8a
    0x10d13cf8a


    编译器就是这么做的,记住就行了,不必太纠结。
    对linux来说,程序加载后内存是分段的。
    screenshot

    验证:

    include
    int main(){

    char a[]="abc";
    char b[]="abc";

    char *c="abc";
    char *d="abc";

    printf("%pn", a);
    printf("%pn", b);
    printf("%pn", c);
    printf("%pn", d);
    }
    结果:

    @ ➜ ~ ./a.out
    0x7fff52ac3afc
    0x7fff52ac3af8
    0x10d13cf8a
    0x10d13cf8a

    0 0
  • xumaojun
    2019-07-17 19:32:45

    编译器就是这么做的,记住就行了,不必太纠结。
    对linux来说,程序加载后内存是分段的。
    screenshot

    验证:

    include
    int main(){

    char a[]="abc";
    char b[]="abc";

    char *c="abc";
    char *d="abc";

    printf("%pn", a);
    printf("%pn", b);
    printf("%pn", c);
    printf("%pn", d);
    }
    结果:

    @ ➜ ~ ./a.out
    0x7fff52ac3afc
    0x7fff52ac3af8
    0x10d13cf8a
    0x10d13cf8a

    0 0
  • nothingfinal
    2019-07-17 19:32:44

    编译器就是这么做的,记住就行了,不必太纠结。
    对linux来说,程序加载后内存是分段的。
    screenshot

    验证:

    include
    int main(){

    char a[]="abc";
    char b[]="abc";

    char *c="abc";
    char *d="abc";

    printf("%pn", a);
    printf("%pn", b);
    printf("%pn", c);
    printf("%pn", d);
    }
    结果:

    @ ➜ ~ ./a.out
    0x7fff52ac3afc
    0x7fff52ac3af8
    0x10d13cf8a
    0x10d13cf8a

    0 0
  • a123456678
    2019-07-17 19:32:44

    编译器就是这么做的,记住就行了,不必太纠结。
    对linux来说,程序加载后内存是分段的。
    screenshot

    验证:
    
    #include<stdio.h>
    int main(){
        char a[]="abc";
        char b[]="abc";
        
        char *c="abc";
        char *d="abc";
        
        printf("%p\n", a);
        printf("%p\n", b);
        printf("%p\n", c);
        printf("%p\n", d);
    }
    结果:
    
    @ ➜  ~  ./a.out
    0x7fff52ac3afc
    0x7fff52ac3af8
    0x10d13cf8a
    0x10d13cf8a
    0 0
添加回答

集结各类场景实战经验,助你开发运维畅行无忧

推荐文章
相似问题