strlen函数是用来求字符串有多少个字符数量的函数,以"\0"作为结束标志,但是计数的时候不会把\0也算进去。比如说我有个字符串"ABCDEF",此字符串默认末尾有个\0但是利用strlen计算结果个数是6,不会把\0也算进去。
#include
#include
int main()
{
const char* str = "ABCDEF";//字符串默认是常量是不可修改的,所以用const修饰
size_t ret=strlen(str);
printf("%zd", ret);
}
同样上述字符串也可以写成字符串数组的格式,结果也是一样的
#include
#include
int main()
{
const char arr[] = "ABCDEF";//字符串默认是常量是不可修改的,所以用const修饰
size_t ret=strlen(arr);
printf("%zd", ret);
}
数组里面单独arr表示的是数组首元素地址,那么字符串str是不是也是首元素地址呢?
其实str确实是传了首元素A的地址给strlen函数,strlen函数本质上接收的就只是字符串首元素的地址,然后往后挨个找\0的位置,返回\0之前有多少个元素个数。
请注意strlen函数返回的是个数,个数一般来说不可能是负数,也不会有除了整数之外的类型,不会有什么一个半(1.5)个数。所以返回值ret要用size_t(无符号整数接收),而不是用习惯的int类型接收
1.首先sizeof函数是关键字,不是库函数,可以直接使用,不用包含头文件
2.sizeof是求字节长度的关键字而strlen是字符串库函数,sizeof函数可以求所有类型的字节大小,因为所有类型都有字节大小啊,比如一个int类型占4个字节,char占一个字节大小,求字符串字节大小会把字符串隐藏的\0也会一块计算了。
而strlen函数一般是只能用在字符串中的,是用来计算有多少个字符的,虽然字符串末尾会默认隐藏字符\0,但是strlen函数不会把\0也一块计算了。
以下是sizeof和strlen函数求字符个数的代码区别
#include
#include
int main()
{
const char str[] = "ABCDEF";
size_t ret = sizeof(str)/sizeof(str[0]);
printf("%zd", ret);
}
需要注意的是,sizeof里面单独一个数组名,表示的是求整个数组大小的字节长度,例如上述代码sizeof(str)表示求整个str的地址,而不是首元素地址。整个字符串数组字节大小除以首元素单个字节大小sizeof(str[0]),就得到元素个数了
strlen求字符串大小
#include
#include
int main()
{
const char str[] = "ABCDEF";
size_t ret = strlen(str);//此时str表示首元素地址
printf("%zd", ret);
}
strlen没把\0算进去,所以是6
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
请注意char * str和char str []两种字符串表示方法,strlen都能用,结果都是一样的,都是传首元素地址给strlen函数用。但是sizeof求字节长度却是不一样的结果
为什么结果是8呢,改变一下字符串改为ABCDEFG看看
结果依旧一样
这是因为你用指针变量保存字符串的地址,sizeof(str)意思是求字符串指针变量str的字节大小,而此时str内部保存的是字符串首元素地址,而32位平台下地址的大小默认全为4个字节,64位平台下默认是8个字节。
#include
size_t my_strlen(const char* str)
{
size_t count = 0;
while (*str)//*str此时是首元素A,遇到字符串隐藏的\0就会停下来,字符\0ascall码值是0
//所以循环遇到0为假会直接跳出
{
count++;
str++;//str从A位置一直往后偏移,每移一次count值加一次,相当于计数
}
return count;
}
int main()
{
const char* str = "ABCDEF";//指针变量str保存首元素地址
size_t ret=my_strlen(str);//本质上传的是首元素地址
printf("%zd", ret);
}
strcpy函数功能其实就是把一个字符串复制到另一个字符串上,前提是目标空间足够大,以确保能放下整个复制过来的字符串。
其次,目标空间必须是可修改的,而被复制的字符串没有修改的必要,所以会被const修饰
被复制的字符串必须以\0结束,同时会把这个\0复制到目标空间当中去
代码表现形式为 char * strcpy(char * destination,const char * source);
destination为目标字符串,即目的地,要复制到这里
source为被复制的字符串
#include
#include
int main()
{
char str[20] = { 0 };//先用0全部填充
const char* stc = "ABCDEF";
strcpy(str, stc);
printf("%s", str);
}
#include
char * my_strcpy(char* str, const char* stc)//用指针的形式来接收传过来的地址
{
char* p = str;//用指针p来保存最初str指向的首元素位置
while (*stc != 0)//到字符串结束标志\0停下来
{
*str = *stc;//字符串stc的元素挨个复制过去
str++;
stc++;
}
return p;//str最初的位置随着++已经改变,而p保存了最初的位置
}
int main()
{
char str[20] = { 0 };
const char* stc = "ABCDE";
my_strcpy(str, stc);//实质都是传了首元素地址
printf("%s", str);
}
strncpy可以指定复制字符串的个数,比如上字符串ABCDEF,我现在只想复制AB过去,strcpy是整个ABCDEF都复制过去了,而strncpy可以只复制两个字符
表现形式为char * strncpy(char* destination,const char * source,size_t num);
size_t num为用复制多少个字符过去
将源字符串的前 num 个字符复制到目标。如果在复制 num 个字符之前找到源字符串的末尾(由 null 字符表示),则 destination 将用零填充,直到总共写入 num 个字符。
如果 source 的长度大于 num,则不会在目标末尾隐式追加 null 字符。因此,在这种情况下,destination 不应被视为以 null 结尾的 C 字符串(这样读取它会溢出)。
同时目的地和源不得重叠
#include
#include
int main()
{
char str[20];
const char* stc = "ABCD";
strncpy(str, stc,2);
printf("%s", str);
}
#include
char* my_strncpy(char* str, const char* stc,int num)
{
char * p = str;
while (num)
{
*str = *stc;
str++;
stc++;
num--;
}
*str= '\0';
return p;
}
int main()
{
char str[20];
const char* stc = "ABCD";
my_strncpy(str, stc,2);
printf("%s", str);
}
与strcpy的代码实现大致相同,只是用num去控制循环赋值的次数。同时strncpy复制过后的字符串不会有'\0',所以要在末尾加上字符串结束标志
末尾不设置‘\0’的代码及运行结果
#include
char* my_strncpy(char* str, const char* stc,int num)
{
char * p = str;
while (num)
{
*str = *stc;
str++;
stc++;
num--;
}
return p;
}
int main()
{
char str[20];
const char* stc = "ABCD";
my_strncpy(str, stc,2);
printf("%s", str);
}
strcat可以理解为字符串追加函数,比如一个字符串str"ABCD",这是常量字符串,已经不能修改了。此时我有另一字符串stc"EFG"要加在字符串str的后面,这就需要strcat函数来实现。
字符串末尾都会有个结束标志‘\0’,而strcat函数会把目的地字符串str末尾的‘\0'用源字符串stc的首元素D直接覆盖,并且会把stc的末尾’\0'复制过去,成为字符串str“ACBCDEFG"的新末尾结束标志
源字符串必须以‘\0’结束
目标空间也得有‘\0’,否则没法知道追加从哪里开始
目标空间必须有足够大,能容下源字符串的内容
目标空间必须可修改
strcat表现形式为
char * strcat ( char * destination, const char * source );
#include
#include
int main()
{
char str[20] = "ABCD";
const char* stc = "EFGH";
strcat(str, stc);
printf("%s", str);
}
要先找到目的地字符串函数的末尾结束标志“\0”才能依次往后循环赋值
#include
#include
char* my_strcat(char* str, const char* stc)
{
char* p = str;//保存字符串的首地址,一遍后面打印
while (*str)//字符串末尾结束标志\0,它的ascall码值是0,循环条件为假跳出循环
//这样就找到了\0的位置
{
str++;
}
while (*stc != '\0')//此循环与上面循环是平行关系,并不是嵌套,stc="\0"说明已经赋值完了
{
*str++ = *stc++;
}
return p;
}
int main()
{
char str[20] = "ABCD";
const char* stc = "EFGH";
my_strcat(str, stc);
printf("%s", str);
}
strncat也是和strcat多了一个限制数量,但是依旧要补上\0
char * strncat ( char * destination, const char * source, size_t num );
#include
#include
int main()
{
char str[20] = "ABCD";
const char* stc = "EFGTYU";
strncat(str, stc, 3);
printf("%s", str);
}
可以看到只拼接了EFG,因为我只限制3个字符拼接
#include
#include
char* my_strncat(char* str, const char* stc, int num)
{
char* p = str;
while (*str)//找到*str为\0的位置
{
str++;
}
while (num)
{
num--;
*str++= *stc++;
}
return p;
}
int main()
{
char str[20] = "ABCD";
const char* stc = "EFGTYU";
my_strncat(str, stc, 3);
printf("%s", str);
}
strcmp函数是比较字符串当中字符大小的
如果第一个字符串大于第二个字符串,则返回大于0的数字;
第一个字符串等于第二个字符串,则返回0;
第一个字符串小于第二个字符串,则返回小于0的数字
strcmp函数比较两个字符串大小是通过ascll码值来进行比较的,如果第一个字符与另一个字符串的首字符相等,则开始比较他们的下一个字符的大小,依次类推。
比如"ABCDEF"和"ABCEFG",前三个字符都相当,所以要从第四个字符来开始比较
int strcmp ( const char * str1, const char * str2 );
#include
#include
int main()
{
const char* str = "ABCFGH";
const char* stc = "ABCTHY";
int ret = strcmp(str, stc);//返回整数,所以用int类型接收
if (ret > 0)
{
printf("大于\n");
}
else if (ret == 0)
{
printf("等于\n");
}
else
{
printf("小于\n");
}
}
#include
#include
int my_strcmp(const char* str, const char* stc)
{
while (*str == *stc&&*str!='\0'&&*stc!='\0')
{
str++;
stc++;
}
if (*str > *stc)
{
return 1;
}
else if (*str < *stc)
{
return -1;
}
else
return 0;
}
int main()
{
const char* str = "ABCFGH";
const char* stc = "ABCFGH";
int ret = my_strcmp(str, stc);
if (ret > 0)
{
printf("大于\n");
}
else if (ret == 0)
{
printf("等于\n");
}
else
{
printf("小于\n");
}
}
依旧是加上比较的次数,比较str与字符串stc的前num个字符,如果相等就继续往后比较,最多比较num个字母,如果提前发现不一样就提前结束,大的字符所在的字符串大于另一个。如果num个字符都相等,就是相等返回0;
int strncmp ( const char * str1, const char * str2, size_t num );
#include
#include
int main()
{
const char* str = "ABCDE";
const char* stc = "ACFGH";
int ret=strncmp(str, stc, 3);
if (ret == 0)
printf("相等\n");
if (ret < 0)
printf("小于\n");
if (ret > 0)
printf("大于\n");
}
strncmp的实现
#include
#include
int my_strncmp(const char* str, const char* stc,int num)
{
num = num - 1;
while (*str == *stc&&num)//大致实现都和strcmp差不多,只是多了num为限定条件
{
if (*stc == '\0')
{
return 0;
}
num--;
stc++;
str++;
}
if (*str < *stc)
return -1;
else if (*str > *stc)
return 1;
else
return 0;
}
int main()
{
const char* str = "ABCDE";
const char* stc = "ABC";
int ret=my_strncmp(str, stc, 3);
if (ret == 0)
printf("相等\n");
if (ret < 0)
printf("小于\n");
if (ret > 0)
printf("大于\n");
}
ABCDE与ABCD测试结果
ABCDE与A的测试结果
ABCD与ABC的测试结果