字符串指针和字符串数组的区别与联系

在C语言当中字符串数组和字符串指针都是用来指向或者存储一段string的。但是栈上字符串指针指向的内容确实不可以修改的。
本博客参考文献:
字符串数组和指针对于sizeof与strlen的区别与影响:
https://blog.csdn.net/cx2479750196/article/details/81288989

字符串数组

//字符串数组
#include <stdio.h>
#include <string.h>
int main(){
    char str1[] = "123456";
	char str2[]={'1','2','3','4','5','6','\0'};
    char str3[]={'1','2','3','4','5','6'};
    
    int len1 = strlen(str1);
	int size1=sizeof(str1);
	printf("%d, %d\n",len1,size1);
	//结果 6,7
	int len2 = strlen(str2);
	int size2=sizeof(str2);
	printf("%d, %d\n",len2,size2);
	//结果 6,7
	int len3 = strlen(str3);
	int size3=sizeof(str3);
	printf("%d, %d\n",len3,size3);
	//结果 随机数,6
    return 0;
}

可以发现使用不同的方式进行初始化的时候,直接使用""方式进行初始化时候,会隐式的加入’\0’来作为结束符。并且使用单独赋值str3类似的方式的时候,因为是没有添加结束符号的,所以在使用strlen时,会一直寻找结束符,会得到一个随机的数字。

字符串指针

//字符串数组
#include <stdio.h>
#include <string.h>
int main(){
    char* str1 = "123456";
    int len1 = strlen(str1);
	int size1=sizeof(str1);
	printf("%d, %d\n",len1,size1);
	//结果 6,8
    return 0;
}

可以发现如果使用指针来指向一个字符串的时候,strlen依然是从指向的地址开始,然后寻找结束符。但是sizeof()用来求变量 、数组、对象、结构体等所占空间的大小是,所以sizeof一个字符串指针的时候返回的时候char*的大小,在32位机器里为4,在64位机器里为8。

字符串数组和字符串指针的修改

在定义为字符串数组和字符串指针后,如果我们想要修改里面的一些值,会出现以下情况:

char* str1 = "123456";
char str2[] = { '1','2','3','4','5','6','\0' };
// 尝试修改字符串指针指向的字符串中第1位的值:失败
str1[1] = '0'; 
// 尝试字符串第1位的值:成功
str2[1] = '0';

可以发现用char* 指针指向的值居然是不可改变的,char[]的值可以正常改变。
原因:char[] 存储在全局数据区或栈区,char*字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。所以尝试对在常量区的字符串进行赋值时错误的。

字符串指针指向堆上开辟的空间

有一种情况,我们需要对字符串指针指向的字符串进行修改。那就需要使用内存分配。使用malloc进行内存开辟,应为该函数的返回值为void,所以需要进行类型的强制转换。空间使用完毕之后,需要使用free将内存空间进行清理,换给操作系统。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   char* str1="Hello"; \\这样声明的变量,变量在栈上
   char* str2=(char*) malloc((sizeof(str1)+1)*sizeof(char)); \\这样声明的变量,变量在堆上
   if(str2==NULL){
	   printf("error");\\需要检验是否开辟空间成功
	   return 1;
	}
   strcpy(str2,str1);\\进行赋值
   printf("%s\n",str2); \\输出结果:Hello
   str2[0]='h';
   printf("%s\n",str2);\\输出结果:hello 
   free(str2);  \\释放开辟的空间
   str2=NULL;
   return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值