使用方法:
int 整形变量 = strlen(数组名);
首先我们看官方给出的函数参数和定义
可以看到,strlen的参数是一个地址,当我们要求一个字符串数组的长度是,给上数组首元素的地址即可,而字符串长度的计算是以 \0为标准的,也就是说,什么时候遇到 \0 ,什么时候就会停止计算长度,我们来模拟实现一下。
#define _CRT_SECURE_NO_WARNINGS
#include
int my_strlen(char* p) //获取数组首元素地址,返回类型int
{
int i = 0;//创建一个 i 变量来计算数组长度
while (*p++) //p解引用的值作为循环条件,当*p == \0,循环停止
{
i++;//每次解引用后的值不等于\0,i++,
}
return i; //返回i,i存储的就是字符串的长度
}
int main()
{
char arr[] = {"123456789"};
printf("%d\n",my_strlen(arr));
printf("%d",strlen(arr));
return 0;
}
使用方法:
int 整形变量 = sizeof(参数);
sizeof计算的是给定参数的大小(以字节为单位),如果给上数组,那么计算的就是数组的大小,sizeof(数组名)计算的是数组的大小,那么使用sizeof(数组名) 除 sizeof(数组下标为0的元素)就能求出数组中有多少个元素。
#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int arr1[] = {1,2,3,4,5};
char arr2[] = {"12345"};
double arr3[] = {1.2,3.14,6.5};
short arr4[] = {1,2,3,4,5};
printf("arr1 = %d \n", sizeof(arr1) / sizeof(arr1[0]));
printf("arr2 = %d \n", sizeof(arr2) / sizeof(arr2[0]));
printf("arr3 = %d \n", sizeof(arr3) / sizeof(arr3[0]));
printf("arr4 = %d \n", sizeof(arr4) / sizeof(arr4[0]));
printf("arr1 = %d 字节\n", sizeof(arr1));
printf("arr2 = %d 字节\n", sizeof(arr2));
printf("arr3 = %d 字节\n", sizeof(arr3));
printf("arr4 = %d 字节\n", sizeof(arr4));
return 0;
}
使用方法:
int 整形变量 = strcmp(数组名1,数组名2);
strcmp比较两个字符串的时候,是一个字节一个字节比较的,比如说:abcdef和abcdeq比较,当比较到f和q时,按照ASCII码比,q的ASCII码值比f的要大,所以后者要比前者大,假设arr1和arr2比较,strcmp(arr1,arr2),如果arr1 > arr2,返回一个大于0的数字,如果arr1 < arr2,返回一个小于0的数字,如果arr1 == arr2,返回0。
下面我们来模拟实现一下strcmp。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int my_strcmp(const char* p1, const char* p2)
{
while (1)
{
if (*p1++ > *p2++)
{
//只要有一个字符大,直接返回1
return 1;
}
else if (*p1 < *p2)
{
//只要有一个字符小,直接返回 -1
return -1;
}
else if (*p1 == '\0' && *p2 == '\0')
{
//如果两个字符串都遇到了\0,说明两个字符串之前都是一样的,那么返回0
return 0;
}
}
}
int main()
{
char arr1[] = {"abcdef"};
char arr2[] = {"abcde"};
int i = my_strcmp(arr1, arr2);
int j = strcmp(arr1,arr2);
if (i > 0)
{
printf("arr1大");
}
else if (i < 0)
{
printf("arr2大");
}
else
{
printf("一样大");
}
printf("\n");
if (j > 0)
{
printf("arr1大");
}
else if (j < 0)
{
printf("arr2大");
}
else
{
printf("一样大");
}
return 0;
}
使用方法:
char * 字符指针 = strcpy(数组名1,数组名2)
模拟实现:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
char* my_strcpy(char* p1, const char* p2)
{
char* p = p1;//记录下 p1 的地址,也就是拷贝后字符串的地址
//将 p1 和 p2 的元素交换,交换一次 ++一次,直到将\0拷贝纸p1,拷贝结束
while (*p1++ = *p2++)
{
;
}
return p;//返回第一个元素的地址
}
int main()
{
char arr1[30] = {"*****************************"};
char arr2[] = {"hello world!!!"};
printf("%s",my_strcpy(arr1,arr2));
return 0;
}
拷贝后,会将\0也拷贝过去,所以现在arr1中的内容是:
因此只会打印到第一个\0的位置
使用方法:
char* 字符指针 = strcat(数组名1,数组名2);
#define _CRT_SECURE_NO_WARNINGS
#include
char* my_strcat(char* p1,const char* p2)
{
char* p = p1;
while (*p1 != '\0')//将p1的位置++到最后,也就是字符串末尾
{
p1++;
}
while (*p1++ = *p2++)//然后将p2的内容依次追加到p1
{
;
}
return p;//返回p1的起始位置
}
int main()
{
char arr1[20] = {"hello "};
char arr2[] = {"world!!!"};
printf("%s",my_strcat(arr1,arr2));
return 0;
}
追加字符串会先找到\0的位置再进行追加,然后从\0的位置开始覆盖,所以arr1追加后的内容是:
使用方法:
char* 字符指针 = strncpy(数组名1,数组名2,字节);
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char arr1[20] = {"*******************"};
char arr2[20] = {"###################"};
int arr3[20] = {1,2,3,4,5,6,7,8,9};
int arr4[20] = {0,0,0,0,0,0,0,0,0};
strncpy(arr1,arr2,1);//将起始位置往后1个字节的内容拷贝到arr1中
printf("%s\n",arr1);
strncpy(arr1,arr2,5);//将起始位置往后5个字节的内容拷贝到arr1中
printf("%s\n",arr1);
strncpy(arr3,arr4,4);//将起始位置往后4个字节的内容拷贝到arr3中
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d",arr3[i]);
}
printf("\n");
strncpy(arr3, arr4, 36);//将起始位置往后36个字节的内容拷贝到arr3中
for (i = 0; i < 9; i++)
{
printf("%d", arr3[i]);
}
return 0;
}
使用方法:
char* 字符指针 = strncmp(数组名1,数组名2,字节);
strncmp比较字符串,可以自己设置要比较的的内容,如果要比较前5个字节的内容,只需要把5传给函数即可,返回值和strcmp是一样的。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char arr1[] = {"abcdef"};
char arr2[] = {"abcdefd"};
int i = strncmp(arr1,arr2,4);
int z = strncmp(arr1,arr2,5);
int y = strncmp(arr1,arr2,7);
printf("%d\n",i);
printf("%d\n",z);
printf("%d\n",y);
return 0;
}
使用方法:
char* 字符指针 = strncat(数组名1,数组名2,字节);
和strcat不同的是,strcat是追加整个数组,而strncat是你想要追加几个字节的内容,就会追加几个字节的内容。
使用方法:
char* 字符指针 = strstr(数组名1,数组名2);
在一个字符串中查找另一个字符串
如果有,返回被查找的字符串首元素地址,如果没有返回NULL.
我们来模拟实现一下
#define _CRT_SECURE_NO_WARNINGS
#include
char* my_strstr( char* p1, char* p2)
{
char* tmp1 = p1;
char* tmp2 = p2;
char* p = tmp1;
while (*p)
{
p1 = p;
p2 = tmp2;
while (*p1 != '\0' && *p2 != '\0' && (*p1 == *p2))
{
p1++;
p2++;
}
if (*p2 == '\0')
{
return p;
}
p++;
}
return NULL;
}
int main()
{
char arr1[] = { "abccccd" };
char arr2[] = { "ccd" };
char* p = my_strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到");
}
else
{
printf("%s", p);
}
return 0;
}
这个函数的使用方法就比较复杂了。
首先假设有一个字符串是[email protected]
我们要将zhangsan,11,com 分解出来。
也就是说按照符号的分割,截取字符串。
我们知道在上述的字符串当中有两个符号,@ .
我们先将@和.存入一个字符串指针中
然后在使用与strstr函数进行分割
char *p = “@.”;
strstr(arr,p);
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
char arr1[] = {"[email protected]"};
char arr2[100];
//使用strstr函数会直接修改数组中的内容,所以我们将数据拷贝到另一个数组中
strcpy(arr2,arr1);
//将分割的符号存入一个字符指针
char* p = "@.";
//第一次使用strtok函数,会自动找到@符号,并将@符号改成\0,然后返回@符号之前的字符串首元素地址
//除了第一次使用,传参需要字符串首元素地址,往后使用都传NULL即可
/*char* str = strtok(arr2,p);
printf("%s\n",str);
//第二次使用,strtok会自动保存上一次@符号的位置,从@符号的位置往后号分隔符,将第二个分割付改成\0,返回第二个分隔符分割的字符串首元素地址
str = strtok(NULL,p);
printf("%s\n",str);
//第三次使用,从第二个分隔符往后找,如果遇到\0,会默认找完了,返回第二个分隔符后的字符串首元素地址
str = strtok(NULL, p);
printf("%s\n", str);*/
char* str;
//这里我们用一个for循环来使用这个函数
for (str = strtok(arr1, p); str != NULL; str = strtok(NULL, p))
{
printf("%s\n",str);
}
return 0;
}
使用方法:
char* 字符指针 = memcpy(数组名1,数组名2,字节);
我们来模拟实现一下:
#define _CRT_SECURE_NO_WARNINGS
#include
void* my_memcpy(void* p1,const void* p2,size_t num)
{
void* p = p1;
while (num--)
{
*((char*)p1)++ = *((char*)p2)++;
}
return p;
}
int main()
{
int arr1[] = {1,2,3,4,5,6,7,8,9};
int arr2[] = {6,6,6,6,6};
my_memcpy(arr1, arr2, 20);
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d ",arr1[i]);
}
printf("\n");
char arr3[] = {"*****************************"};
char arr4[] = {"hello world!!!"};
char* p = my_memcpy(arr3,arr4,14);
printf("%s", p);
return 0;
}
memcpy和strncpy很相似,但是memcpy可以拷贝任意类型的数据,并且是以字节为单位的,想拷贝几个字节的数据只需要在参数商做修改即可
使用方法:
char* 字符指针 = memmove(数组名1,数组名2,字节);
memmove和memcpy的使用方法是一样的,但是有一点强于memcpy,比如说,有一个数组,内容是1 2 3 4 5 6,现在我要将 1 2 3拷贝到 4 5 6的位置上,将数组的前三个元素,拷贝到后三个元素商,就会变成123123,而memcpy做不到这个功能。
#define _CRT_SECURE_NO_WARNINGS
#include
void* my_memmove(void* p1,const void* p2,size_t num)
{
void* p = p1;
if (p1 < p2)
{
while (num--)
{
*((char*)p1)++ = *((char*)p2)++;
}
}
else
{
while (num--)
{
*((char*)p1 + num) = *((char*)p2 + num);
}
}
return p;
}
int main()
{
int arr1[] = {1,2,3,4,5,6,7,8,9};
char arr2[] = {"aaaaabbbbb"};
my_memmove(arr1+3,arr1,16);
my_memmove(arr2+5,arr2,5);
printf("%s\n",arr2);
int i = 0;
for (i = 0; i < 9; i++)
{
printf("%d ",arr1[i]);
}
return 0;
}
使用方法:
memset(数组名1,修改内容,字节);
memset,将指点字节的内容进行修改
#define _CRT_SECURE_NO_WARNINGS
#include
#include
int main()
{
int arr[] = {1,2,3,4,5};
memset(arr,0,16);
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ",arr[i]);
}
return 0;
}