字符串的全面解析

目录

前言:

字符串的赋值

  字符串的初始赋值两种:

  输出的形式:

  输入赋值四种方法:

  在函数中的赋值(复制):

小问题:

字符串处理函数string:

多维字符串:

为什么非要在字符串后加'\0'的问题。

子函数调用字符串:

字符串的错误使用方法:

通过单个元素的比较方式比较大小;


前言:

        首先我们需要了解什么是字符串;字符串本质上是一种以'\0'结尾的字符数组;其实我们所说的字符串,是用数组来保存字符的一种形式;这个数组里都是字符,所以我们把它称作字符串,但在C语言中,并没有字符串变量,仅仅是借用数组,来表示字符串

字符串的赋值

  字符串的初始赋值两种:

   第一种整体赋值:

char  a[]={"good morning"};//因为保存的是字符型的变量所以数组用char来定义;
char  b[]="good morning";//可以不加{}
    

这种形式会在最后一个字符的末尾加'\0',是以'\0'结尾的;

如果定义的字符长度小于数组的下标,则其他元素自动为'\0';

空格也算一个字符;

如果用这种方法来定义字符串,则定义的字符个数要少数组的下标,因为在末尾会自动加'\0';(当然'\0',也是会占一个字符的位置;'\0'为转义字符 null(空))

       编译器会在末尾自动添加'\0'是为了清楚,该字符串是在那里结束。'\0'作为字符串结束的标志。(具体为什么下面的多维数组讲解

           注:空格和'\0',并不是同一个东西。空格是字符;ASCII码是32,而'\0'是转义字符;ASCII码是0

   第二种单个元素赋值:

char a[]={'g','o','o','d'};//这种形式必须带花括号{};

这种形式末尾是没有'\0';的,相当于对数组中的每一个元素进行赋值。

能定义的字符个数就等于数组的下标值;(这种形式更准确的来说应该叫字符数组)

   第三种指针法:

char *p="hello";//定义一个指针指向一个字符串;
printf("%s",p);//输出字符串;
printf("%c",*(p+i));//单个字符输出;

指针p指向字符串的首地址,如果需要调用可以*(p+i)这种形式取其中的元素;或直接p输出这个字符串;

       虽然C语言中没有表示字符串的变量,但是有输出字符串形式的格式符“%s”

  输出的形式:

printf("%s",a);//将数组中的所有元素进行输出;
printf("%c",a[i]);//将数组中的第i个元素输出;
puts(a);//输出字符串;
putchar(a[i]);//单字符输出,一次输出一个字符;

  输入赋值四种方法:

     方式1.整体输入gets方式:

char s1[];//这里根据自己需求定义长度即可;
gets(s1);//直接输入字符串(字符串中可以加空格)

这种方式最简单实用,如果是多个字符串,那么需要有与之对应的gets();与之对应。

     方式2.单个字符赋值:

char s1[];
for(i=0;i<n;i++)
s1[i]=getchar();//一次只能接受一个字符,区分清楚getchar和putchar的形式;

输入时不要一个字符一个回车;回车和'/0'都是转义字符,也占位置;('\r':回车)

      方式3.整体输入,scanf形式:

char s1[];
scanf("%s",s1);//直接输入字符串中不可以有空格,末尾自动加'\0';(s1前不用加'&'取地址符)

  和其他变量赋值一样,用空格来分隔输入的变量;空格或回车结束输入;

多个字符串输入要有与之对应的'%s';切记'%s'之间不要乱加字符来分隔,如果加上,在输入过程中需要原样输入,区别中英文。不过可以加空格来隔开。

     方式4.单字符输入,scanf形式:

char s1[];
for(i=0;i<n;i++)
scanf("%c",&s1[i]);//如果是单字符输入需要加'&';

和方式2同理,不要一个字符一个回车;

  在函数中的赋值(复制):

1.单个元素复制:

char s1[50],s2[30]={"hello"};
for(i=0;s2[i]!='\0';i++)
s1[i]=s2[i];
S1[i]='\0';//根据需要在结尾加'\0',表结束;

2.利用库函数string:

#include<string.h>//使用前要声明;
char s1[50],s2[50]="hello";
strcpy(s1,s2);//s1必须是数组名且长度不低于被复制的字符串;
strcpy(s1,"hello");//s2可以是数组名,或者字符串常量;

将s2中的字符串包括'\0'全部复制过去;

小问题:

如果s1长度低于s2的长度,会出错,但是可以执行;且长度是被复制的长度,这里我不太清楚,有知道的大佬,可以留言解答一下;

#include<stdio.h>
#include<string.h>
int main()
{
	char s1[3],s2[50]={"good boy"};
	int m;
	strcpy(s1,s2);
	m=strlen(s1);
	printf("%s\n%d",s1,m);
return 0;
}

3.指针法赋值:

       其实和上述两种方法一样,只要清楚指针的指向,以及取值应用即可。

#include<stdio.h>
int main()
{
	int i;
	char s1[10],s2[20]="good man",*p1,*p2;
	p1=s1;p2=s2;
	for(i=0;s2[i]!='\0';i++)//s2[i]等于'\0'结束
	p1[i]=p2[i];
    puts(p1);
return 0;
}

字符串处理函数string:

再上面赋值时,提到过,使用前得声明

strcpy:用于字符串的复制,上面讲到了;

strlen:用于测量字符串长度;到'\0'结束,实际长度不包括'\0';也就是说如果字符串中间有'\0',会在此处结束;如上例图;形式为:strlen(s1);

strcat:用于字符串的连接;将s2接到s1后面;s1须足够长,再连接时,将s1中首个'\0'

去掉,将s2接到后面,保留s2的'\0';这里注意一下是碰到首'\0',  形式为:strcat(s1,s2);

strcmp:用于两个字符串的比较大小;形式为:strcmp(s1,s2)

s1=s2;//返回值为0;

s1>s2;//返回值为正整数;

s1<s2;//返回值为负整数;

字符串的大小问题:

有的小伙伴,可能不太清楚,sizeof和strlen的区别。

strlen是计算字符串的长度,它的计算方法是遇到'\0',就结束。

#include<stdio.h>
#include<string.h>
int main()
{
	char a[10]="abc\0lk";
	printf("%d",strlen(a));
	return 0; 
	}

这个的结果为3。

sizeof是计算字符串整体所占的内存单元,包括'\0'在内,查看一共占了多少内存单元。

#include<stdio.h>
#include<math.h>
#include<string.h>
int main()
{
	char a[10]="abc\0lk";
	printf("%d",sizeof(a));
	return 0; 
	}

这个的结果为10。

多维字符串:

       一维数组构成一个字符串,多维数组,构成多个字符串,具体的个数取决于二维数组的行下表;

char s1[2][30]={"hello","world"};
char s2[2][30]={
   
   {'h','e','l','l','o'},{'w','o','r','l','d'}};

和上述的几种方法来赋值是一样;只要知道调用字符串时,调用的是他的数组名即可方便使用;

如 :strcmp(s1[0],s2[1]);

为什么非要在字符串后加'\0'的问题。

我们来看一个例子就清楚了;

#include<stdio.h>
int main()
{
	char s[2][5]={"good","boys"};
	printf("%s",s[0]);
return 0;
}

#include<stdio.h>
int main()
{
	char s[2][5]={"good","boys"};
	s[0][4]='s';
	printf("%s",s[0]);
return 0;
}

 

       如果没有'\0';我们要想单个比较或使用某一个字符串,他就会顺带将其下一条也带上,因为没有'\0'作为结束标志,程序会接着输出或使用下一个字符串,直到碰到'\0'为止;

子函数调用字符串:

int fun(char s1[],char s2[])
{
	int i;
	if(strcmp(s1,s2)>0)return 1;
	else return 0;
}
int main()
{          
           int i=1,m;
	char s1[2][30]={"hello","world"},
     s2[2][30]={
   
   {'h','e','l','l','o'},{'w','o','r','l','d'}};
        m=fun(s1[1],s2[0]);
         printf("%d",m);
         return 0;
}

       传递的是字符串的首地址;在子函数中,定义好接收的类型,字符型数组,返回值看需要进行定义;如果是单独的字符,就和整型是一样的。

          如果传送的是单个字符的地址,那么就需要由一个字符型指针来接收

int fun(char *s1,char *s2)
{
	int i;
	if(*s1>*s2)return 1;
	else return 0;
}
int main()
{          
           int i=1,m;
	char s1[2][30]={"hello","world"},
     s2[2][30]={
   
   {'h','e','l','l','o'},{'w','o','r','l','d'}};
        m=fun(&s1[1][1],&s2[0][2]);
         printf("%d",m);
         return 0;
}

字符串的错误使用方法:

char s1[50];
s1="good";//错误的赋值方式;
s1=s2;//错误的赋值方式;

char s1[30]={"hello"},s2[30]={'w','o','r','l','d'};
if(s1>s2);//错误的比较方法;

如过不想通过调用字符串函数string来比较字符串的大小,可以这样;

通过单个元素的比较方式比较大小;

#include<stdio.h>
int main()
{
	int i=0;
	char s1[10]={"hello"},s2[20]="world";
 while((s1[i]!='\0')&&(s2[i]!='\0'))
	{ 
 if(s1[i]>s2[i])printf("s1>s2");
 if(s1[i]<s2[i])printf("s1<s2");
 i++;
 }
if(s1[i]==s2[i])printf("s1=s2");
return 0;
}

好了以上就是本章内容,如果错误地方,请立刻指正,谢谢。

猜你喜欢

转载自blog.csdn.net/weixin_67118900/article/details/124235584
今日推荐