ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

常见函数

2022-06-16 22:02:41  阅读:146  来源: 互联网

标签:00 函数 dest 常见 char printf NULL arry


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有