学习字符串的第一天

在艰难的梳理完指针中的四个比较难区分的概念后,在今天开始了字符串的学习。

#include<stdio.h>

int main(){
	int array[]={1,2,3,4,5};
	char carray[]={'h','e','l','l','o'};
	char carray2[]="world";//可以改变
	char *parray="hello";//字符串常量,不能改变
	
	/*char *p;//野指针,危险,但这里看不到段错误。
	*p='a';
	printf("%c",*p);
	*/
	
	printf("%s\n",carray2);
	printf("%s",parray);
	carray2[2]='l';//*parray='m';这个指令会造成段错误
	putchar('\n');
	puts(parray);
	puts(carray2);
	
	/*
	for(int i=0;i<5;i++){
		printf("%c",*parray++);
	}
	*/
	
	return 0;
}

通过这段代码,可以了解到多种能够定义出一串字符串,虽然有些定义的方法看起来跟数组一样(有点low),但char string[ ]=" ";这种方法还是比较如人意的,既可以连贯的定义出字符串,后续也可以通过string[ ]= ;来对某一个字符进行更改。值得注意的是char *pstr=" ";的这种定义方法,定义出来的是字符串常量,后续不能改变。

#include<stdio.h>

int main(){
	int array[]={1,2,3,4,5};
	char carray[]={'h','e','l','l','o'};
	char carray2[]="world";//字符串最后带有结束标志'\0'
	
	int len;
	
	len=sizeof(array)/sizeof(array[0]);
	printf("%d\n",len);
	
	len=sizeof(carray)/sizeof(carray[0]);
	printf("%d\n",len);
	
	len=sizeof(carray2)/sizeof(carray2[0]);
	printf("%d\n",len);
	
	return 0;
}

第二段代码主要是让我知道了字符串的最后带有结束标志'\0',通过用关键字sizeof来计算没有规定长度的字符串的长度可以看出,字符串的长度要比字母的个数长一个字节,而这个字节就是用来存放结束标志'\0'的。

#include <stdio.h>
#include <string.h>

void test()
{
	
}

int main(){
	char cdata[666]="hello";
	void (*ptest)();
	ptest=test;
	char *p="hello!";
	
	printf("sizeof :%d\n",sizeof(cdata));
	printf("strlen :%d\n",strlen(cdata));//strlen计算有效长度
	printf("sizeof(ptest)   :%d\n",sizeof(ptest));
	printf("sizeof(p)       :%d\n",sizeof(p));
	printf("strlen(p)       :%d\n",strlen(p));//计算p指向地址中的有效长度
	printf("sizeof(char*)   :%d\n",sizeof(char*));
	printf("sizeof(int*)    :%d\n",sizeof(int*));
	printf("sizeof(char)    :%d\n",sizeof(char));
	printf("sizeof(int)     :%d\n",sizeof(int));
	
	return 0;
}                                                                                                                                              

第三段代码用来区分sizeof和strlen。本质上来讲,两者大不相同:sizeof属于关键字,而strlen是一个函数。想要使用strlen函数必须包含头文件<string.h>。通过对代码中的cdata[666]="hello"分别使用sizeof和strlen可以看出strlen返回的是字符串的有效长度,原理就是检测字符串的结束标志'\0',而sizeof则计算出整个cdata的长度。在实际的应用中,我们需要根据不同的需求来使用两者。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
	char *p;
	
	p=(char *)malloc(1);
	*p='v';
	free(p);
	
	p=(char *)malloc(10);
	if(p == NULL){
		printf("malloc error\n");
		exit(-1);
	}
	memset(p,'\0',10);
	printf("扩容前的地址:%x\n",p);
	int len =strlen("jhfdrufoiuykjkh");
	int newLen=len - 10 + 1;
	realloc(p,newLen);
	printf("扩容后的地址:%x\n",p);
	strcpy(p,"jhfdrufoiuykjkh");
	puts(p);
	puts("done");
	
	return 0;
}

今天的最后一段代码,是学习malloc动态开辟内存空间留下的。虽然只有这一点点内容,但却是我今天花费时间最长的。先是以为对例子代码中的NULL不理解,查阅了本站几个关于malloc函数用法的文章,了解了NULL,弄懂了malloc的用法。但由于后续strcpy的使用中出现了对超出长度的字符串正常输出的情况,我就想了很多方法去找到不一样的原因,以及为什么会出现这种情况。比如我在strcpy前后分别用strlen计算p的长度,得到的结果分别是3和strcpy中字符串对应的长度。这令我很奇怪,为什么malloc分配的空间自动扩容了。于是我有用sizeof重复计算,结果都是8。现在冷静下来一想,这根本就是傻子行为。sizeof(p)计算的是计算机用来储存地址的空间大小,当然都是8个字节了。后来答疑助手告诉我这能运行是运气,这是在非法使用内存,只是因为被使用的内存我现在还用不上,所以一直能够正常运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值