其他分享
首页 > 其他分享> > 常见函数

常见函数

作者:互联网

C函数

函数是C语言的基本组成单位。

1.char* strcpy(char * destination, const char * source)拷贝

函数复刻

my_strcp(char* dest,const char* src){
    assert(dest != NULL);
    assert(src != NULL);
    while(*dest++ = *src++){
        ;
    }
}
int main(){
  char arr1[] = {"hello"};
  char arr2[10] = {"worldworld"};
  //destination 要拷贝到的变量
  //source 要拷贝的变量
  strcpy(arr2,arr1);
  printf("arr1:%s\n",arr1);//hello
  printf("arr1:%s\n",arr2);//hello
  return 0;
}

众所周知,字符串类型若不手动在字符串后添加结束符"\0",则会默认加上结束符。
strcpy()函数也会将源变量中的结束符拷贝到目标变量中,形成如下情况

  arr1:'h','e','l','l','0','\0';
  arr2:'h','e','l','l','0','\0','o','r','l','d','\0';

拷贝完成后,目标数组只有前半部分完全复制源数组(包括源数组的结束符),而其余不变,输出目标数组,只截取到源数组的结束符,所以才会只显示复制数组的结果。

2.unsigned int strlen(char * str)字符长度

函数复刻

int my_strlen(const char* string){
    assert(string != NULL);
    int result = 0;
    while(*string){
        string++;
        result++;
    }
    return result;
}
int main(){
   char * arr1 = {"hello"};
   char * arr2[10] = {"hello"};
   char * arr3[5] = {"hello"};
   printf("%d\n",strlen(arr1));//5
   printf("%d\n",strlen(arr2));//5
   printf("%d\n",strlen(arr3));//21
   return0
}
int main() {
    char arr1[]="abcdefg";
    char arr2[]={'a','b','c','d','e','f','g'};
    char arr4[]={'a','b','c','d','e','f','g',0};
 
    //strlen() return unsinged int
     printf("%d\n",strlen(arr1));//7
     printf("%d\n",strlen(arr2));//14
     printf("%d\n",strlen(arr3));//7
     printf("%d\n",strlen(arr4));//7
     return 0;
 }
  1. 当字符数组初始化时不定义大小,输出为字符串长度
  2. 当字符数组初始化时定义大小,且字符串长度不占满字符数组大小,输出为字符串长度
  3. 当字符数组初始化时定义大小,且字符串长度占满字符数组大小,输出为不定值!

3.printf()

该函数的返回值为打印字符的个数。

int main(){
	printf("%d",printf("%d",printf("%d",43)));//4321
}

代码分析:最内层的printf函数打印的是43,返回值是2;那么上一层printf打印的就是2,返回值就是1;最外层printf打印的就是上一层的返回值1,所以结果就是4321。

4.sizeof() 参数所占空间的大小

char arry[]="abcd";
sizeof(arry);//该数组位char数组,该数组所占空间为4*1=4位
sizeof(arry[0]);//数组的首字符所占空间大小1
length=sizeof(arry)/sizeof(arry[0]);//总空间/单个空间,就是字符的个数

5. strcat() 追加字符串

函数复刻

my_strcat(char* dest,char* src){
    assert(dest != NULL);
    assert(src != NULL);
    //1.先移动(找到)到目标字符串的结束符位置\0
    while(*dest){
        dest++;
    }
    //2.再将原字符串追加至目标函数
    while (*dest++ = *src++);
}

注意:1.dest字符串的长度要足够放下src字符串 .

6. strcmp(char* str1,char* str2) 比较字符串

函数复刻

int my_strcmp(const char* str1,const char* str2){
    //1.进来的指针不能为空
    assert(str1 != NULL);
    assert(str2 != NULL);
    //2.逐个字符判断是否相同
    while(*str1 == *str2){
        //若字符为’\0‘,则证明两个字符串都到达结束字符,则相同
        if(*str1 == '\0'){
            return 0;
        }
        //指针后移一位
        str1++;
        str2++;
    }
    //若逐个字符不同,上循环代码已将指针移到不同字符的位置,则即可拿来判断(ascii码判断)
    if(*str1 > *str2){
        //检查,输出第一对不同的字符
        printf("str1=%c\tstr2=%c\n",*str1,*str2);
        return 1;
    }
    else{
        printf("str1=%c\tstr2=%c\n",*str1,*str2);
        return -1;
    }
}

若str1==str2,则返回0;
若str1 > str2,则返回大于0的数(不一定是1);
若str1 < str2,则返回小于0的数(不一定是-1).

7. char* strstr(const char* string, const char* setstring) 是否包含子串

函数复刻

char* my_strstr(const char* str,const char* instr){
    //1.判断参数是否为空
    assert(str && instr);
    //2.原指针不动,新建指针移动
    char* p1 = str;
    char* p2 = instr;
    char* current = str;//当前指针位置,用来记录第一次出现字串的起始位置
	   //如果子串为'\0',返回子串
    if(*p2 == '\0')
        return p2;
    //3.遍历字符串
    while(*current){
        //用p1与p2比较,current进行移动再赋值给p1
        p1 = current;//父串的起始位置一直后移
        p2 = instr;//重置子串的指针位置为起始位置
        //str不为结束符,instr不为结束符,且str和instr字符相同时,指针才后移
        while ((*p1 != '\0') && (*p2 != '\0') && (*p1 == *p2)){
            p1++;
            p2++;
        }
        //instr遍历完成到结束符证明已找到子串,返回current临时指针
        if(*p2 == '\0'){
            return current;
        }
        current++;
    }
    return NULL;
}

返回值是字串第一次出现的位置(指针),若不存在,返回NULL。

8.char* strtok(char* str1,const char* str2) 分割字符串

函数复刻

     //char* arr="abc";abc是放在字符常量区的,是不可修改的
    //char arr[]="abc";abc是放在栈中的,是字符常量区的一份拷贝,可修改
    char str1[]="www@baidu?com";
    char* str2="@?";
    char* result = NULL;
    for(result = strtok(str1,str2);result!=NULL;result = strtok(NULL,str2)){
        printf("%s\n",result);
    }

char str[30] = "litianyi@hust.educn";
	char seps[] = ".@";
	char* s1 = NULL;
	//第一次调用时strtok函数找到@符号,将@符号改为'\0',记录位置,
	//下次调用时strtok函数从'\0'处开始向后切割字符串,所以之后调用传递NULL即可
	//可以分析得出strtok函数内部必有static修饰的局部变量
	s1 = strtok(str, seps);
	printf("%s\n", s1);//litianyi
	//再次调用时找到'.',将‘.'改为'\0',返回hust,记录位置
	s1 = strtok(NULL, seps);
	printf("%s\n", s1);//hust
//第三次调用时,返回educn,记录位置
	s1 = strtok(NULL, seps);
	printf("%s\n", s1);//educn
}

注意:参数1需传入字符数组形式的字符串(可修改)。
该函数是将字符串中出现的分隔符替换成'\0',以实现分段字符串。

9. char* strerror(int num) 返回错误信息

printf("%s\n", strerror(0));
printf("%s\n", strerror(1));
printf("%s\n", strerror(-1));
printf("%s\n", strerror(2));
//No error
//Operation not permitted
//Unknown error
//No such file or directory
//errno是一个全局的错误代码变量,当程序出错即可使用该函数查看错误情况
File* pf = open("test.txt","r");
if(pf == NULL){//如果该文件不存在,则打印错误信息
    printf("%s\n", strerror(errno));
}
//NO SUCH A FILE

该函数传入不同的数字,以返回不同的错误信息。

10.void* memcpy(void* dest,const void* src, int size)内存拷贝

函数复刻

void* my_memcpy(void* dest,const void* src,int size){
    void* result = dest;//
    //1.传参非空指针
    assert(dest != NULL);
    assert(src != NULL);
    //拷贝的长度并自减为循环条件
    while(size--){
        *(char*)dest = *(char*)src;//逐个字节拷贝
        (char*)dest++;//逐个字节(强转)后移
        (char*)src++;
    }
    return result;
}

注意:目标数组dest的长度应是确定的。且该函数在c语言标志规定下不推荐内存重叠情况的移动场景。而该场景由下函数实现。

11.void* memmove(void* dest,const void* src,size_t count) 内存重叠移动

函数复刻

void* my_memmove(void* dest,const void* src,size_t count){
    assert(dest != NULL);
    assert(src != NULL);
    void* result = dest;
    //count = count*4;//count*字节数
    //目标位置小于原位置,从前到后拷贝
    if(dest<src){
        while(count--){
            *(char*)dest = *(char*)src;
            (char*)dest++;
            (char*)src++;
        }
    }
    else{
        //后向前拷贝
        while (count--){
            *((char*)dest+count) = *((char*)src+count);
        }
    }
    return result;
}

使用案例

    int arr[]={1,2,3,4,5,6};
    my_memmove(arr+2,arr,3*sizeof(int));
    for(int i= 0;i<sizeof arr/sizeof arr[0];i++){
        printf("%d ",arr[i]);
    }
//1 2 1 2 3 6

12. memset(void* dest,int c,size_t count)

| dest:要设置的目标
| c: character to set (要设置的字符)
| count: 要设置的字节数(单位1)

使用案例

   char arr[5] = {};
   memset(arr,'#',5);
  //arr[5] = ['#','#','#','#','#'];

  //小端存储
  //00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  int arr[5] = {0};
  memset(arr,1,10);
  //01 01 01 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 00 00
  //arr = {16843009,16843009,257,0,0}

sizeof()、strlen()

char arry1[] = { 'a','b','c','d' };//数组
	printf("arry[1]:%d\n", sizeof(arry1));//4
	printf("arry[1]:%d\n", strlen(arry1));//15

	char arry3[] = "abcd";//字符串
	printf("arry[3]:%d\n", sizeof(arry3));//5
	printf("arry[3]:%d\n", strlen(arry3));//4

	char arry2[4] = { 'a','b','c','d' };
	printf("arry[2]:%d\n", sizeof(arry2));//4
	printf("arry[2]:%d\n", strlen(arry2));//16

	char arry6[4] = "abcd";
	printf("arry[6]:%d\n", sizeof(arry6));//4
	printf("arry[6]:%d\n", strlen(arry6));//28


	char arry4[10] = { 'a','b','c','d' };
	printf("arry[4]:%d\n", sizeof(arry4));//10
	printf("arry[4]:%d\n", strlen(arry4));//4

	char arry5[10] = "abcd";
	printf("arry[5]:%d\n", sizeof(arry5));//10
	printf("arry[5]:%d\n", strlen(arry5));//4
	
	int arry7[] = { 1,2,3,4,5 };
	printf("arry[7]:%d\n", sizeof(arry7));//20=4*5
	printf("arry[7]:%d\n", strlen(arry7));//1strlen只能求字符串长度

	int arry8[10] = { 1,2,3,4,5 };
	printf("arry[8]:%d\n", sizeof(arry8));//40
	printf("arry[8]:%d\n", strlen(arry8));//1

标签:00,函数,dest,常见,char,printf,NULL,arry
来源: https://www.cnblogs.com/DC-Flash/p/16383730.html