关于sizeof/strlen、char */char []

#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<map>
#include<unordered_map>
#include<unordered_set>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;



int main()
{
	char *s1 = "hello";
	char s2[] = "hello";

	//char s2[5] = "hello";     //这里会报错,因为s2末尾还有一个'\0'结束符,字符数组长度少1;

	string st = "hello";		//st存在栈中,"hello"可以经由st修改;

	cout << "sizeof   s1:" << sizeof(s1) << endl;
	/* 程序输出的是4,即32位系统中指针变量的大小*/
	/*char *s1 = "hello";实际上先是在文字常量区分配了一块内存放"hello",
	然后在栈上分配一地址给s1并指向这块地址*/

	cout << "strlen   s1:" << strlen(s1) << endl;
	/*程序输出5,strlen遇到'\0'即结束计算,char *s1 最后包含一个'\0'结束符*/

	cout << "sizeof   s2:" << sizeof(s2) << endl;
	/*程序输出6,sizeof计算字符串实际占有的空间大小,包括了结尾的'\0'结束符*/

	cout << "strlen   s2:" << strlen(s2) << endl;
	/*程序输出5,strlen遇到'\0'即结束计算,s2最后包含一个'\0'结束符*/

	//cout << "lenght of st:" << strlen(st) << endl;
	//报错,因为strlen只接受char *类型参数;
	cout << "length of st:" << st.length() << endl;
	//程序输出5,结尾不含有'\0';

	cout << s1 << endl;
	//返回从s1开始的字符串"hello";
	cout << s2 << endl;
	//返回从s2开始的字符串"hello"
	cout << *s2 << endl;
	//返回第一个字符'h'
	cout << *(s2 + 1) << endl;
	//返回第二个字符'e'
	cout << (s1 + 1) << endl;
	//s1自身就是地址,无法取*操作,返回第二个字符开始的字符串"ello"
	cout << &s2[1] << endl;
	//返回从第二个字符开始的字符串"ello"


	//s1[4] = 'M';
	//程序报错,因为s1指向的"hello"是常量,不能通过s1修改;

	s2[4] = 'M';
	cout << s2 << endl;
	//程序正常运行,输出"hellM";

	//s2 = "world";
	/*该句报错,系统提示:s2是一个普通字符数组首地址,"hello"存在栈区,可以通过s2修改"hello",s2必须
	是可修改的左值,s2类似一个const指针*/

	st[4] = 'M';
	cout << st << endl;
	//程序输出"hellM"
	return 0;
}

总结如下

1. char[] p表示p是一个数组指针,相当于const pointer,不允许对该指针进行修改。但该指针所指向的数组内容,是分配在栈上面的,是可以修改的。

2. char * pp表示pp是一个可变指针,允许对其进行修改,即可以指向其他地方,如pp = p也是可以的。对于*pp = "abc";这样的情况,由于编译器优化,一般都会将abc存放在常量区域内,然后pp指针是局部变量,存放在栈中,因此,在函数返回中,允许返回该地址(实际上指向一个常量地址,字符串常量区);而,char[] p是局部变量,当函数结束,存在栈中的数组内容均被销毁,因此返回p地址是不允许的。


同时,从上面的例子可以看出,cout确实存在一些规律:

1、对于数字指针如int *p=new int; 那么cout<<p只会输出这个指针的值,而不会输出这个指针指向的内容。
2、对于字符指针入char *p="sdf f";那么cout<<p就会输出指针指向的数据,即sdf f

那么,像&(p+1),由于p+1指向的是一个地址,不是一个指针,无法进行取址操作。

&p[1] = &p + 1,这样取到的实际上是从p+1开始的字符串内容。


分析上面的程序:

*pp = "abc";

p[] = "abc";

*pp指向的是字符串中的第一个字符。

cout << pp; // 返回pp地址开始的字符串:abc

cout << p; // 返回p地址开始的字符串:abc

cout << *p; // 返回第一个字符:a

cout << *(p+1); // 返回第二个字符:b

cout << &p[1];// 返回从第二个字符开始的字符串:bc


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值