char *s和char s[]的区别与联系以及strlen()和sizeof()的用法

#include<iostream>
using namespace std;

void reverse(char s[])
{
	char *p, *q, temp;
	p = s;//p指向字符串s的第一个字符
	q = s + strlen(s) -1;//q指向字符串s的最后一个字符。
	while(p < q)
	{
		temp = *p;//交换两字符
		*p = *q;
		*q = temp;
		p++;
		q--;
	}
}
int main()
{
	char s[] = "ABCDE";
	char *p = s;
	char *q = s + strlen(s) - 1;
	cout << "交换前:" << endl;
	while(p <= q)
	{
		cout << *p <<" ";
		p++;
	}
	cout << endl;

	reverse(s);

	char *p1 = s;
	char *q1 = s + strlen(s) - 1;
	cout << "交换后:" << endl;
	while(p1 <= q1)
	{
		cout << *p1 <<" ";
		p1++;
	}
	system("pause");
	return 0;
}

运行结果如下:


需要注意的知识点:

一:char *s和char s[]的区别与联系:

char *s1 = "hello";
char s2[] = "hello";

【区别所在】

char *s1 的 s1 是指针,而指针是指向一块内存区域,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。
char s2[] 的 s2 是数组,对应着一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变。

【内存模型】
   s1: |  *======> | h | e | l | l | o |\0 |
   s2: | h | e | l | l | o |\0 |
    

场景一)
char *s1 = "hello";
char s2[] = "hello";
s2=s1;  //编译ERROR
s1=s2;  //OK

分析:s2其地址和容量在生命期里不能改变


场景二)
char s2[] = "hello";
char *s1 = s2;  //编译器做了隐式的转换 实际为&s2

char *s1 = &s2;

分析:以上两个指针赋值完全等价,由于编译器会做这个隐式转换也容易导致初学者误认为 char *s 与char s[]是一回事。另用第二种在一些编译器甚至会报警告信息。


场景三)
char *s1 = "hello";
char s2[] = "hello";
s1[0]='a';  //×运行ERROR( 这一句好像在一些的编译器不会出错,原因待查)
s2[0]='a';  //OK

分析:运行时会报错,原因在于企图改变s1的内容,由于s1指向的是常量字符串,其内容是不可修改的,因此在运行时不会通过。而s2指向的是变量区字符串,可以修改。所以在上面程序中应用void reverse(char s[])而不是 void reverse(char *s).


场景四)
让我们来给一个指针的指针赋值,在使用某些含char**参数的函数时会用到,场景二的增强版。
    char *s1="hello";
    char s2[]="hello";
    char *s3=s2;       //★注意这句必须要★
    char **s4=&s3;  

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值