C语言进阶教程之字符串&内存函数

C语言进阶教程之字符串&内存函数

字符串

字符串的定义

在C语言中,字符串是由一串字符组成的数组。数组中的元素都是字符类型,每一个字符都是占1个字节的ASCII码。字符串以'\0'结尾,'\0'称为空字符(null character),也就是字符串的结束标志。

下面是一个包含字符串的数组的定义:

char str[] = "Hello World!";

这个字符串由12个可见字符和一个隐藏的空字符('\0')组成,所以它的长度为13个字节。

字符串的读取

gets函数

在C语言中,可以通过调用gets()函数从标准输入中读取一个字符串,它的原型如下:

char *gets(char *s);

示例代码如下:

#include <stdio.h>

int main() {
    char str[50];

    printf("Enter a string: ");
    gets(str);

    printf("You entered: %s\n", str);

    return 0;
}

在运行时,会让用户输入一个字符串,然后将输入的字符串赋值给str,最后打印输入的字符串。

fgets函数

gets()函数已经被弃用,因为它存在安全问题,也就是它读取的字符串长度必须小于缓冲区长度,否则会发生缓冲区溢出。为了解决这个问题,C语言还提供了一个更安全的函数fgets()

fgets()函数可以读取指定长度的字符串,因此比gets()函数更安全。它的原型如下:

char *fgets(char *s, int size, FILE *stream);

其中,size表示允许读取的最大字节数,stream表示输入的数据流。如果读取成功,fgets()函数返回所读取的字符串,如果出现错误或者到达文件结尾,返回NULL

示例代码如下:

#include <stdio.h>

int main() {
    char str[50];

    printf("Enter a string: ");
    fgets(str, 50, stdin);

    printf("You entered: %s\n", str);

    return 0;
}

在运行时,它会让用户输入一个长度小于50字节的字符串,并将输入的字符串赋值给str,最后打印输入的字符串。

字符串的拼接

在C语言中,可以通过调用strcat()函数将两个字符串拼接在一起,它的原型如下:

char *strcat(char *dest, const char *src);

其中,dest表示拼接后的目标字符串,src表示需要拼接的源字符串。需要注意的是,dest字符串必须有足够的空间容纳src字符串,否则会发生缓冲区溢出。

示例代码如下:

#include <stdio.h>
#include <string.h>

int main() {
    char str1[20] = "Hello ";
    char str2[] = "World!";

    strcat(str1, str2);

    printf("The concatenated string is: %s\n", str1);

    return 0;
}

在运行时,它会将str2拼接到str1的末尾,最后打印拼接完成的字符串。

内存函数

内存函数的定义

在C语言中,有一些内存函数可以用来操作内存中的数据。这些函数通常被用来动态分配内存、释放内存、复制内存等。

内存分配函数

malloc函数

malloc()函数可以动态分配内存空间,它的原型如下:

void *malloc(size_t size);

其中,size表示需要分配的字节数,返回分配到的内存空间的起始地址。如果分配失败,则返回NULL

示例代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
   int *ptr;
   int n = 5;

   ptr = (int*)malloc(n * sizeof(int));

   if (ptr == NULL) {
      printf("Memory allocation failed!\n");
      exit(0);
   }

   for (int i = 0; i < n; i++) {
      ptr[i] = i + 1;
   }

   printf("The elements of the array are: ");

   for (int i = 0; i < n; i++) {
      printf("%d ", ptr[i]);
   }

   free(ptr);

   return 0;
}

在运行时,它会分配5个整型变量大小的内存空间,然后将其中的值进行打印,并最后释放内存空间。

calloc函数

calloc()函数与malloc()函数类似,它也可以用来动态分配内存空间,不同之处在于calloc()在分配内存时会将内存空间初始化为0,而malloc()函数不会。它的原型如下:

void *calloc(size_t nmemb, size_t size);

其中,nmemb表示需要分配的元素个数,size表示每个元素的大小,返回分配到的内存空间的起始地址。如果分配失败,则返回NULL

示例代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
   int *ptr;
   int n = 5;

   ptr = (int*)calloc(n, sizeof(int));

   if (ptr == NULL) {
      printf("Memory allocation failed!\n");
      exit(0);
   }

   for (int i = 0; i < n; i++) {
      printf("%d ", ptr[i]);
   }

   free(ptr);

   return 0;
}

在运行时,它会初始化5个整型变量大小的内存空间,然后将其中的值进行打印,并最后释放内存空间。

realloc函数

realloc()函数可以用来重新分配内存空间,它的原型如下:

void *realloc(void *ptr, size_t size);

其中,ptr表示需要重新分配内存空间的指针,size表示需要分配的新的内存空间大小。如果分配成功,则返回新的内存空间地址,否则返回NULL。需要注意的是,如果ptrNULL,则等价于调用malloc()函数。

示例代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr;
    int n1 = 5, n2 = 10;

    ptr = (int*)malloc(n1 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        exit(0);
    }

    for (int i = 0; i < n1; i++) {
        ptr[i] = i + 1;
    }

    ptr = realloc(ptr, n2 * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        exit(0);
    }

    for (int i = n1; i < n2; i++) {
        ptr[i] = i + 1;
    }

    printf("The elements of the array are: ");

    for (int i = 0; i < n2; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr);

    return 0;
}

在运行时,它会分配5个整型变量大小的内存空间,并将其中的值进行打印。接着,它通过调用realloc()函数重新将内存大小重新分配为10个整型变量大小,然后将其中的值进行打印,并最后释放内存空间。

内存释放函数

free函数

free()函数可以用来释放由malloc()calloc()realloc()函数动态分配的内存空间。它的原型如下:

void free(void *ptr);

其中,ptr表示需要释放的内存空间地址。

示例代码如下:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr;
    int n = 5;

    ptr = (int*)malloc(n * sizeof(int));

    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        exit(0);
    }

    for (int i = 0; i < n; i++) {
        ptr[i] = i + 1;
    }

    printf("The elements of the array are: ");

    for (int i = 0; i < n; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr);

    return 0;
}

在运行时,它会分配5个整型变量大小的内存空间,并将其中的值进行打印。接着,它通过调用free()函数释放内存空间。

内存复制函数

memcpy函数

memcpy()函数可以用来复制内存空间中的数据,它的原型如下:

void *memcpy(void *dest, const void *src, size_t n);

其中,dest表示目标内存空间地址,src表示源内存空间地址,n表示需要复制的字节数。

示例代码如下:

#include <stdio.h>
#include <string.h>

int main() {
    char src[50] = "Hello World!";
    char dest[50];

    memcpy(dest, src, strlen(src) + 1);

    printf("The copied string is: %s\n", dest);

    return 0;
}

在运行时,它会将源字符串src复制到目标字符串dest中,然后打印复制完成的字符串。

memmove函数

memmove()函数与memcpy()函数类似,也可以用来复制内存空间中的数据,不同之处在于当源内存区域与目标内存区域重叠时,memmove()函数能够保证复制过程正确。它的原型如下:

void *memmove(void *dest, const void *src, size_t n);

其中,dest表示目标内存空间地址,src表示源内存空间地址,n表示需要复制的字节数。

示例代码如下:

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "memmove can work with overlapping areas!";

    memmove (str+20, str+15, 11);

    printf ("Result: %s\n", str);

    return 0;
}

在运行时,它会将源字符串中部分字符复制到目标字符串的后面,然后打印复制完成的字符串。

总结

本文介绍了C语言中的字符串和内存函数。字符串是由一串字符组成的数组,可以通过gets()或者fgets()函数读取字符串,通过strcat()函数拼接字符串。内存函数包括动态分配函数、内存释放函数、内存复制函数,可以通过malloc()calloc()realloc()函数动态分配内存空间,通过free()函数释放内存空间,通过memcpy()memmove()函数复制内存空间中的数据。这些函数在C语言程序中有着广泛的应用,能够提高程序的灵活性和效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言进阶教程之字符串&内存函数 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Centos8使用Squid配置代理服务器的详细过程

    下面就为大家讲解一下CentOS 8如何使用Squid配置代理服务器的详细过程。 环境准备 在开始配置Squid代理服务器之前,需要确保你的CentOS 8系统已经正确连接互联网。安装Squid之前,还需安装epel-release和squid软件包: sudo yum install -y epel-release sudo yum install -y …

    other 2023年6月27日
    00
  • 中文版Win10预览版9879官方ISO镜像下载地址(附安装教程)

    中文版Win10预览版9879官方ISO镜像下载地址(附安装教程) 1. 下载镜像文件 首先,你需要下载中文版Win10预览版9879的官方ISO镜像文件。你可以通过以下步骤进行下载: 步骤一:打开你的浏览器,访问微软官方网站。 步骤二:在搜索框中输入“中文版Win10预览版9879官方ISO镜像下载”,然后按下回车键进行搜索。 步骤三:在搜索结果中找到微软…

    other 2023年8月4日
    00
  • 小米4悄然升级Android 6.0.1:版本号也变成了MMB29M

    小米4悄然升级Android 6.0.1: 版本号也变成了MMB29M攻略 小米4是一款备受欢迎的智能手机,最近悄然升级到了Android 6.0.1,并且版本号也变成了MMB29M。本攻略将详细介绍如何升级小米4的操作步骤。 步骤一:备份重要数据 在进行任何系统升级之前,我们强烈建议您备份重要的数据。这可以防止数据丢失或损坏。您可以通过以下方式备份数据: …

    other 2023年8月3日
    00
  • arcgis10.2之地图服务的发布、使用

    当然,我很乐意为您提供ArcGIS 10.2之地图服务的发布和使用攻略。以下是详细的步骤和示例: 步骤1:了解ArcGIS 10.2地图服务 ArcGIS 10.2地图服务是一种基于ArcGIS Server的Web服务,它可以将GIS数据发布到Web上,以便用户可以在Web浏览器中查看和查询地图数据。地图服务可以包含多个图层,每个图层可以包含多个要素类。 …

    other 2023年5月6日
    00
  • vue中对接Graphql接口的实现示例

    下面我将就“vue中对接GraphQL接口的实现示例”的完整攻略给出详细说明。 1. 什么是GraphQL GraphQL 是 Facebook 开源的一种用于 API 开发的查询语言。它将客户端和服务器之间的 API 数据交流变得更加高效灵活。与传统的 RESTful API 不同,GraphQL 允许客户端告诉服务器需要什么数据,而服务器仅仅返回客户端请…

    other 2023年6月27日
    00
  • tomcat访问管理页面出现:403accessdenied解决方法

    tomcat访问管理页面出现:403accessdenied解决方法 当我们在使用tomcat进行web开发或管理时,经常需要访问tomcat管理页面。但是有时候会遇到访问管理页面时出现:403accessdenied的情况,这是什么原因,该如何解决呢? 什么是:403accessdenied :403accessdenied是指服务器拒绝了互联网用户的访问…

    其他 2023年3月29日
    00
  • Android5.1系统通过包名给应用开放系统权限的方法

    Android 5.1系统通过包名给应用开放系统权限的方法攻略 在Android 5.1系统中,可以通过以下步骤给应用开放系统权限: 确定应用的包名:首先,需要确定要给应用开放权限的包名。包名是应用在Android系统中的唯一标识符,可以在应用的清单文件(AndroidManifest.xml)中找到。 编辑系统权限配置文件:接下来,需要编辑系统权限配置文件…

    other 2023年9月7日
    00
  • js中的escape的用法汇总

    js中的escape的用法汇总 1. 什么是escape? 在JavaScript中,escape()函数可以将字符串转换成可传输的格式,通过将某些字符用%xx的格式进行编码,其中xx表示该字符的ASCII码值的十六进制表示。 2. escape()的用法 2.1 编码普通字符 对于尚未被编码的字符,我们只需要直接使用escape()函数即可。例如,对于一个…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部