字符串指针与字符数组的区别[亲测有效]

编程文档 (51) 2023-08-05 18:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说字符串指针与字符数组的区别[亲测有效],希望能够帮助你!!!。

面试常见问题,虽然以前也看过别人写的,但是被面试时还是回答不全面,而且我个人还挺反感的,觉得记住这些有啥用,又不影响开发。但是今天遇到了一个坑,定义了一个字符串指针,传到某个接口中,接口内对字符串进行了修改,出现了Segmentation fault,查了好久,才发现是这个问题,于是痛定思痛,决定整理一下,分享给大家。

字符串指针与字符数组的区别[亲测有效]_https://bianchenghao6.com/blog_编程文档_第1张

1 存储方式不同

字符数组直接储存对象,指针则是指向一个对象

字符数组在内存中占一段连续的单元,所占内存存放的是字符串。定义方法为:

char a[N];N为常量表达式,可初始化。a中数据存放在栈区。

字符指针是指向字符的指针,所占内存单元存放的是所指字符的内存单元(指针存放的是地址),定义方法为:

char *p;p所指向的字符串存放在常量区/文本区。

2 赋值方式不同

数组名不能被赋值,指针变量能。

char *ps = "C Language";

可以写为:

char *ps;
ps="C Language";

而对数组方式:

static char st[] = "C Language";

不能写为:

char st[20];
st = "C Language";

只能对字符数组的各元素逐个赋值,从这点可以看出字符串指针变量与字符数组在使用时的区别,同时也可看出使用指针变量更加方便。

3 获取字符串长度方式不同

示例:

int main(void)
{
    char *test_p = "2";
    char test_a[] = "2";
    printf("p_len=%ld, sizeof:%ld\n", strlen(test_p), sizeof(test_p));
    printf("a_len=%ld, sizeof:%ld\n", strlen(test_a), sizeof(test_a));
}

Linux平台运行结果:

p_len=1, sizeof:8

a_len=1, sizeof:2

sizeof(数组名),得到数组中字符所占内存的大小(字节单位),sizeof(指针),相当于sizeof(void*)。(注意,不同目标平台指针长度可能不同,所以sizeof(void*)是最准确的回答)

⚠️注意:这个位置延申一下,计算字符串长度时,要使用专门的接口strlen,不要用sizeof,区别在于前者不包含'\0',后者包含'\0'。

4 访问方式不同

指针是间接访问,数组是直接访问。

在ANSI C中,初始化指针时所创建的字符串常量被定义为只读(即char* a实际上是const char* a)。如果试图通过指针修改这个字符串的值,程序就会出现未定义的行为。在有些编译器中,字符串常量被存放在只允许读取的文本段或者常量区中,以防止它被修改。

如:在Linux运行会报Segmentation fault。

和指针相反数组字符串存放挡在栈区,所以由字符串常量初始化的数组是可以修改的。其中的单个字符在以后可以改变。

示例:

int main(void)
{
    char test_array[] = "a1:a2:a3:a4";
    test_array[0] = '1';
}

上面这个可以正常运行,下面的会出现Segmentation fault,在嵌入式系统可能会进入hardfault。

int main(void)
{
    char *test_p = "a1:a2:a3:a4";
    test_p[0] = '1';
}

并且数组名不能执行“++”操作,但是指针可以。

发表回复