C语言字符串

238 阅读3分钟

1.字符串初始化

字符串初始化的三种方法:显然第二三种更方便

char cdata1[]={'h','e','l','l','o'};
char cdata2[]="hello";
char *pchar ="hello";

注意第二种和第三种的区别:

1.第二种是字符串"变量",可以修改

2.第三种是字符串"常量",不可修改(但在数组中是可以修改的)

3.注意指针的操作:可以保存地址,修改指向字符串常量的地址空间;但是对野指针的内存空间无法操作

#include <stdio.h>
int main(){
	int data[]={1,2,3,4,5};
	//字符串初始化的三种方法:
	char c='c';
	char cdata1[]={'h','e','l','l','o'};
	char cdata2[]="hello";
	char *pchar ="hello";

	printf("%s\n",cdata2);
	putchar('\n');
	puts(cdata2);
	for(int i=0;i<5;i++){
		printf("%c",*(pchar+i));
	}
}

注意格式控制符为c%

char *p='a';  野指针,并没有明确的内存指向,这种操作非常危险,容易和对其他程序造成影响

2.单双引号的区别

3.字符串的内存存放方式及结束标志

#include <stdio.h>

int main(){
	char cdata1[]={'h','e','l','l','o'};
	char cdata2[]="hello";
	
	printf("cdata1的长度为%d\n",sizeof(cdata1)/sizeof(cdata1[0]));
	printf("cdata2的长度为%d\n",sizeof(cdata2)/sizeof(cdata2[0]));
	}
cdata1的长度为5    

这种建立字符串数组的方式,末尾不会补充“/0”,因此长度为5

cdata2的长度为6     

这种方式,在末尾会自动添加一个“/0”,因此长度为5+1=6

4.sizeof与strlen的区别

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

int main(){
	char cdata1[]={'h','e','l','l','o'};
	char cdata2[]="hello";
	char cdata3[128]={'h','e','l','l','o'};

	printf("cdata1的长度为%d\n",sizeof(cdata1)/sizeof(cdata1[0]));
	printf("cdata2的长度为%d\n",sizeof(cdata2)/sizeof(cdata2[0]));
	
	printf("sizeof:%d\n",sizeof(cdata2));
	printf("strlen:%d\n",strlen(cdata2));
	
	printf("sizeof:%d\n",sizeof(cdata3));
	printf("strlen:%d\n",strlen(cdata3));	
	}
sizeof:6           
strlen:5
sizeof:128
strlen:5

两者大小不同的原因是:strlen函数会丢弃字符“/0”,而sizeof函数不会

char cdata3[128]={'h','e','l','l','o'};中,字符串的长度已经确定为128,
因此sizeof计算结果为128;

但由于初始化时只确定了前5个字符,所以后面的字符均被初始化为‘/0’,
又因为strlen函数主动忽略'/0',所以计算时只考虑前5个有效字符,结果为5

顺带提一句,当不确定变量类型的时候,sizeof(cdata1)/sizeof(cdata1[0]) 来计算元素个数是非常好的解决方式。

void test(){
}
int main(){
char data[128]="hello";
void (*ptest)();
ptest=test;
char *p="hello";

printf("sizeof:data  %d\n",sizeof(data));//字符串长度
printf("sizeof:p     %d\n",sizeof(p));//指针
printf("sizeof:char* %d\n",sizeof(char *));//char指针
printf("sizeof:int*  %d\n",sizeof(int *));//int指针
printf("sizeof:char  %d\n",sizeof(char));//一个char型变量
printf("sizeof:ptest %d\n",sizeof(ptest));//函数指针
}    
sizeof:data  128
sizeof:p     8
sizeof:char* 8
sizeof:int*  8
sizeof:char  1
sizeof:ptest 8

由上述结果可以发现,无论是什么类型的指针变量(int指针、char指针、数组指针、函数指针等),其大小均为8个字节,因为指针变量存放的内容本质是一个地址,而地址的长度是由计算机自身决定的。

5.malloc动态开辟内存空间(防止悬挂指针/野指针)

1.动态内存的开辟与分配
char *p;//野指针
*p='c';
printf("%c\n",*p);
puts("end");
image.png

p=(char *)malloc(1); 此时p有了具体的内存指向,在此基础上,让p去承接‘c’

char *p;
p=(char *)malloc(1);
*p='c';
printf("%c\n",*p);
puts("end");
image.png
2.动态内存的释放
char *p;
p=(char *)malloc(1);
*p='c';
free(p);
p=(char *)malloc(5);
printf("重新分配后的地址为:%p\n",p);
strcpy(p,"hello world");
int len=strlen("hello world");
int newlen=len-5+1;
realloc(p,newlen);//扩容函数
printf("扩容后的地址为:%p\n",p);
strcpy(p,"hello world");
puts(p);//打印字符串
puts("end");

重新分配后的地址为:00000000001E23E0
扩容后的地址为:00000000001E23E0
hello world
end

free(p)释放空间

(char *)malloc(1)分配空间

(int *)malloc(12)

realloc(p,newlength)扩容空间,扩容之后,地址不变,第二个参数为扩容长度

puts(p)打印字符串

6.字符常用操作函数

7.实现字符串拷贝函数

8.断言函数assert

9.字符串拼接strcat

10.字符串比较strcmp