加载中...

简单讨论C中的字符数组相关的问题

1.字符数组跟字符指针有什么区别?

首先我们知道,定义一个字符数组如下:

char arr[ ]= "abbbbbcdfefedfadsf"

定义一个字符指针如下:

char* p2 = "abbbbbcdfefedfadsf";

眨眼一看,感觉确实没什么区别,但我想说的是区别很大。

我们先来了解一下内存的大概存储是如何分布的:

  图一:内存的大致分布

假设,数组跟指针都在main函数中定义,从这个图可以看出数组跟指针都是在栈区开辟空间,因为他们都是局部变量;

好,那么我们从知道了他们都在栈区开始,来开始解答为什么区别很大

(1)从初始化角度看是一样的,都是给他们初始赋值成"abbbbbcdfefedfadsf";这个赋值的字符串存储的空间可不是都在栈区。

  char arr[ ]= "abbbbbcdfefedfadsf";

  char* p2 = "abbbbbcdfefedfadsf";

  arr[ ]中的字符串是一种备份,而指针存入的是字符串的地址;

  备份跟地址后面再说,先埋个伏笔。

(2)字符数组跟字符指针的功能不同。

  你在用char arr[]的时候,虽然不能用arr直接赋值字符串,即 arr = “hello world”;但你可以用arr[ i ],i∈(0~(arr元素个数 - 1)),来改变arr数组的值;

  而字符指针的本质就是指向了一个内存空间,只要是有权可以访问,指针就可以指向该内存区域并修改这个区域的值,所以说指针真的不能乱用好吧。

(3)最后来说说,备份跟地址的事。

  假设定义int arr[ 10 ] = { 0 };

  数组存储的时候,其实是在栈区开辟了一块连续的存储空间;第一个元素arr[ 0 ]为最低的地址,每次地址+1时,依次访问后面的元素,当地址+9时,访问的元素就是arr[ 9 ]。而初始化为0,其实就是把arr[ 0 ] = 0;arr[ 1 ] = 0;......arr[ 9 ] = 0。这就是所谓的备份;

  那么在char arr[ ]= "abbbbbcdfefedfadsf" 这句当中,实际就是把每个字符给到对应元素中,最后一个元素就是放了‘\0’表示字符串结束,当你调试VS或者VC的时候,就可以看到arr[ 0 ] = ‘a’;arr[ 0 ] = ‘b’;......arr[ 18 ] = ‘\0’;

  图二:数组的各个元素情况

因为这是对最初版本(就是"abbbbbcdfefedfadsf")的copy,那肯定是可以改的,所以要对某字符串进行修改可以采用字符数组写法;

那指针可以吗?如果你要修改它所指向的字符串,我们就试试吧。

 图三:程序挂了

好家伙,程序直接崩了。

那现在我们可以知道定义char* p1 = "abbbbbcdfefedfadsf";p1实际上是不可变的,那这个原因我想大家应该看了最上面的图一就知道了,一般来说p1指向的是一块空间,而你单写一段字符串,像"abbbbbcdfefedfadsf",系统会将这个字符串存储到代码段里,这个代码段可牛了,存储的是一种常量,是不可修改的,固定的值。p1指向了不可修改的空间,你要去改它的值,那当然不行。所以我们一般写这种代码,最好写成 const char* p1 = "abbbbbcdfefedfadsf"; 前面的const是修饰*p1整体,表示不可修改p1所指向的值。

2.这两者定义有何区别?

char arr1 [ ] = "abcd" ①

char arr2 [ ] = {‘a’,‘b’,‘c’,‘d’ } ②

我们在VS19run一下

结果很明显了,arr2实际就只有4个元素,刚开始学习的时候很多小伙伴都是认为这两种没什么区别,结果就导致了一些bug的出现,在以后写代码时,要避免这种小错误;

 

最后,总结一下

(1)char* p1 = "abbbbbcdfefedfadsf";写法不严谨,最好写成 const char* p1 = "abbbbbcdfefedfadsf";

(2)如果要修改字符串里的值,写成字符数组形式,一般是在函数传参时,需要特别注意;

(3)char arr1 [ ] = "abcd"  ,char arr2 [ ] = {‘a’,‘b’,‘c’,‘d’ } 两种写法并不等价;

posted @ 2022-03-04 13:20  一名博客  阅读(76)  评论(0编辑  收藏  举报