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语言程序中有着广泛的应用,能够提高程序的灵活性和效率。

阅读剩余 86%

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

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

相关文章

  • uniapp打包安卓App的两种方式(云打包、本地打包)方法详解

    uniapp打包安卓App的两种方式(云打包、本地打包)方法详解 uniapp是一种跨平台的开发框架,可以用于开发多个平台的应用程序,包括安卓App。在uniapp中,我们可以使用两种方式进行安卓App的打包:云打包和本地打包。以下是详细的步骤和示例说明: 云打包方式 登录HBuilderX:首先,确保你已经安装了HBuilderX,并登录你的账号。 创建项…

    other 2023年10月13日
    00
  • 论文笔记之:Conditional Generative Adversarial Nets

    论文笔记之: Conditional Generative Adversarial Nets 简介 Conditional Generative Adversarial Nets,简称CGAN,是一种生成对抗网络(GAN)的扩展。相对于传统的GAN,CGAN在输入噪声向量的基础上,额外输入了条件信息,使得生成的结果能够针对条件信息的不同而变化,具有更好的灵活…

    其他 2023年3月28日
    00
  • 使用navicat导入excel表

    使用Navicat导入Excel表 Navicat是一款强大的数据库管理工具,它包含了许多实用的功能,其中之一就是能够导入Excel表。在本篇文章中,我们将介绍如何使用Navicat导入Excel表。 步骤一:打开Navicat 首先打开Navicat,连接到你的数据库。 步骤二:选择数据库 在连接成功后,选择需要导入Excel表的数据库。 步骤三:选择表 …

    其他 2023年3月28日
    00
  • Windows10纯净版系统右键新建没有office选项如何解决?

    问题背景:当Windows 10系统中缺失Office选项时,用户右键点击空白处新建文件时无法选择Office相关应用程序,需要找到办法恢复Office选项。 解决方案: 步骤一:尝试重新安装Office软件 如果你之前曾经安装过Office应用,可能是由于Office应用程序被误删、卸载或者安装程序出现问题等原因导致Office选项丢失。在这种情况下,你可…

    other 2023年6月27日
    00
  • java并发——dcl问题

    以下是关于“Java并发——DCL问题”的完整攻略: DCL问题 DCL(Double-Checked Locking)问题是指在多线程环境下,使用双重检查锁定机制创建单例对象时,可能会出现线程安全问题。具体来说,当多个线程同时访问单例对象时,可能会创建多个实例,从而导致单例对象失效。 解决方法 以下是一些解决DCL问题的方法: 使用volatile关键字:…

    other 2023年5月9日
    00
  • nginx全局配置和性能优化

    Nginx全局配置和性能优化 Nginx是一款高性能的Web服务器和反向代理服务器,已经成为目前互联网中使用最为广泛的Web服务器之一。为了提高Nginx的性能,我们需要进行全局配置和性能优化。 全局配置 我们可以在Nginx配置文件的全局区域中设置一些全局配置选项,这样可以减少在每个虚拟主机中都进行相同配置的麻烦。以下是几个常用的全局配置选项: worke…

    其他 2023年3月28日
    00
  • 实现图片预加载的三大方法及优缺点分析

    当我们的网站或应用中存在大量图片时,为了提高用户体验,通常会采用图片预加载技术,提前加载页面中需要展示的图片。通过以下三种方式可以实现图片预加载: 1. 使用Image对象 使用Image对象的方式是最简单和原生的预加载方式。创建一个Image对象,设置src属性为图片的URL,然后监听load和error事件来判断图片是否加载完成。代码示例如下: cons…

    other 2023年6月25日
    00
  • Android中bindService基本使用方法概述

    Android中bindService基本使用方法概述 在Android应用开发中,使用Service来进行后台服务的处理是非常常见的一种方式。其中,bindService是其中一种Service的使用方式,它可以实现Activity与Service的通信,让Activity能够与Service交互数据、接收和响应Service的回调。 一、bindServ…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部