字符串,sizeof,strlen,malloc,string.库(strcpy、strcat、strcmp)

  • 字符串

    字符串就是字符数组,可以有两种定义方式。

    #include <stdio.h>
    /*
    字符串的定义
    */
    
    int main()
    {
    	char cdata[] = "hello";//定义了一个字符串变量,可以修改
    	char *pcdata = "hello";//定义了一个字符串常量,不可以被修改
    	
    	printf("%s\n",cdata);
    	printf("%s\n",pcdata);
    	puts(cdata);
    	
    	cdata[1] = 'a';//可以改变其中的值
    	printf("%s\n",cdata);
    	*pcdata = 'm';//不能改变
    	printf("%s\n",pcdata);
    	
    	return 0;
    }
    
  • 字符串和字符数组的区别

    #include <stdio.h>
    /*
    字符串和字符数组的区别
    */
    
    int main()
    {
    	char cdata1[] = {'h','e','l','l','o'};
    	char cdata2[] = "hello";
    	int len1;
    	int len2;
    	
    	len1 = sizeof(cdata1)/sizeof(cdata1[0]);
    	printf("len = %d\n",len);//结果为5
    	
    	len2 = sizeof(cdata2)/sizeof(cdata2[0]);
    	printf("len = %d\n",len);//结果为6
    	
    	return 0;
    }
    /*
    len1和len2差1的区别是,cdata2这个字符串会自动加一个'\0',是字符串结束的标志。
    */
    
  • sizeof和strlen的区别

    #include <stdio.h>
    #include <string.h>
    int main()
    {
    	char cdata[128] = "hello";
    	
    	printf("sizeof cdata = %d\n",sizeof(cdata));//结果128,sizeof是计算整个数组的长度
    	printf("strlen cdata = %d\n",strlen(cdata));//结果5,是计算实际有效字符串的长度
    
    	return 0;
    }
    
  • 动态开辟字符串(包含头文件#include <stdlib.h>)

    1. malloc:

      void* malloc(size_t size)分配所需的内存空间,并返回一个指向它的指针。

      分配一块内存空间,用完之后要用free函数释放。分配内存但在使用完毕后不释放将引起内存泄漏。内存泄漏会增加程序的体积,有可能导致程序或系统的崩溃。malloc只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。

    2. realloc:

      void realloc(void *ptr,size_t size)尝试重新调整之前调用malloc或calloc所分配的ptr所指向的内存块的大小。

      realloc函数返回的是void*类型的指针,指向在堆区重新开辟的内存块的起始地址,memblock是先前开辟的内存块的指针(也就是malloc或calloc之前申请的那块内存空间,即需要调整大小的内存空间),size_t size指的是New size in bytes,新的字节数,注意不是增加的字节数,而是新开辟的那块内存空间的字节数,返回值为调整之后的内存的起始地址。

    3. free:

      void free(void* ptr)释放之前调用的calloc、malloc或realloc所分配的内存空间。

      作用:释放,防止内存泄漏;防止悬挂指针(当指针指向的内存空间已经被释放,但是该指针没有任何的改变,以至于仍然指向已经被回收的内存地址,这种情况下该指针就被称为悬挂指针)。

    4. 初始化置NULL;申请内存后判空;指针释放后置NULL(3个注意点避免野指针)

      int *p;
      p = NULL;//初始化置NULL
      
      p = (char *)malloc(20);
      if(p == NULL){
      	printf("malloc error\n");
      	exit(-1);
      }//申请内存后判断是否为空
      
      free p;
      p = NULL;//指针释放后置NULL
      
    5. memset:

      void *memset(void *s, int c, size_t n);memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值。

      s指向要填充的内存块。

      c是要被设置的值。

      n是要被设置该值的字符数。

      返回类型是一个指向存储区s的指针。

      memset函数是按照字节对内存块进行初始化,所以不能用它将int数组出初始化为0和-1之外的其他值。

  • printf和puts的区别

    1. puts的功能更单一,只能输出字符串;printf可以根据给定的格式输出多种类型的数据。
    2. put输入后会自动换行,而printf输入后需添加\n才能进行换行。
  • scanf与getchar的用法

    1. scanf 语句的意思就是:从键盘上输入字符 125,然后%d将这三个字符转化成十进制数 125,“&n” 找到变量 n 的地址,把数字 125 放到以变量 n 的地址为地址的变量中,即变量 i 中,所以最终的输出结果就是n=125。

      # include <stdio.h>
      int main()
      {
          int n=0;
          scanf("%d", &n);  //&n 表示取变量 n 的地址,&是取地址符
          printf("n = %d\n", i);
          return 0;
      }
      
    2. getchar();

      读取一个字符,连续输入是注意输入缓冲区的回车符,用多用一个getchar函数吸收掉。

  • 练习:完成字符串复制函数

    #include <stdio.h>
    #include <string.h>
    /*
    完成字符串的复制函数
    */
    char* myStrCpy(char *mubiao,char *yuan)
    {
    	if(mubiao == NULL || yuan == NULL){
    		return NULL;
    	}
    	char *p = mubiao;
    	while(*yuan != '\0'){
    		*mubiao++ = *yuan++;
    	}
    	*mubiao = '\0';
    	
    	return p;
    }
    char* myStrNCpy(char *mubiao,char * yuan ,int num)
    {
    	if(mubiao == NULL || yuan == NULL){
    		return NULL;
    	}
    	char *p = mubiao;
    	while(*yuan != '\0' && num >0){
    		*mubiao++ = *yuan++;
    		num--;
    	}
    	if(num > 0){
    		while(num > 0){
    			num--;
    			*mubiao++ = '\0';
    		}
    		return p;
    	}
    
    	*mubiao = '\0';
    	
    	return p; 
    }
    int main()
    {
    	char str[128] = {'\0'};
    	char *p = "hello world,hello world,hello world";
    	
    	myStrCpy(str,p);
    	puts(str);
    
    	memset(str,'\0',128);
    	myStrNCpy(str,p,7);
    	puts(str);
    	
    	return 0;
    }
    
  • 断言函数assert

    #include <assert.h>
    assert(mubiao != NULL && yuan != NULL);//断言
    

    在执行时,如果表达式为false时,assert() 会在标准错误 stderr 上显示错误消息,并中止程序执行。

  • strcat

    strcat函数是字符串追加函数,也就是在字符串后面追加另一个字符串。

    char *strcat(char *_Destination,const char *_Source)

    把str所指向的字符串(包括’\0’)复制到dest所指向的字符串后面(删除dest原来末尾的‘\0’)。要保证*dest足够长,以容纳被复制进来的src。*src中原有的字符不变,返回指向dest的指针。

  • 练习,编写strcat函数

    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    /*
    编程strcat函数
    */
    char* my_strcat(char *des,char *src)
    {
    	assert(des != NULL && src != NULL);
    	char* bak = des;
    	while(*des != '\0'){
    		des++;
    	}
    	while(*src != '\0'){
    		des++ = src++;
    	}
    	*des = '\0';
    	
    	return bak;
    }
    int main()
    {
    	char str[128] = "hello";
    	char *p = " world";
    	//strcat(str,p);
    	my_strcat(str,p);
    	puts(str);
    	
    	return 0;
    }
    
  • strcmp:

    int strcmp ( const char * str1, const char * str2 );
    

    字符串比较函数,用于比较字符串的大小。若str1小于str2,则返回负整数,即小于0的数。若str1和str2相等,则返回0。若str1大于str2,则返回正整数,即大于0的数。

    strcmp本质上比较的是第一位不同位的ASCII码值大小。

  • strncmp:

    int strcmp ( const char * str1, const char * str2 ,size_t n);
    

    把str1和str2进行比较,最多比较前n个字节。

  • 练习,编写strcmp函数

    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    /*
    strcmp字符串比较函数
    */
    
    int my_strcmp(char* str1,char* str2)
    {
    	assert(str1 != NULL && str2 != NULL);
    	while(*str1 == *str2){
    		if(*str1 == '\0'){//两个指针都指向\0 还没跳出while循环,说明两个字符串相等
    			
    			return 0;
    		}
    		str1++;
    		str2++;
    	}
    	
    	if(*str1 > *str2){
    		return 1;
    	}else{
    		return -1;
    	}
    }
    
    int main()
    {
    	char *p1 = "hello";
    	char *p2 = "helol";
    	int ret;
    	
    	ret = my_strcmp(p1,p2);
    	
    	if(ret == 0){
    		puts("p1 = p2");
    	}else if(ret > 0){
    		puts("p1 > p2");
    	}else
    		puts("p1 < p2");
    	
    	return 0;
    }
    
  • 28
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值