C语言:字符串

发布于:2025-04-06 ⋅ 阅读:(24) ⋅ 点赞:(0)

在 C 语言里,字符串是由一系列字符构成,并且以空字符 '\0' 作为结束标志。

1. 字符串的定义和初始化

字符数组形式
#include <stdio.h>

int main() {
    // 使用字符串字面量初始化字符数组
    char str1[]="hello";
    // 初始化字符数组
    

    // 另一种初始化方式
    char str2[10] = {'W', 'o', 'r', 'l', 'd', '\0'};

    // 更简洁的初始化方式
    char str3[10] = "Hello";

    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    printf("str3: %s\n", str3);

    return 0;
}
  1. str1:使用字符串字面量直接初始化字符数组。编译器会自动在字符串末尾添加空字符 '\0'是字符串变量,允许被修改。
  2. str2:逐个字符初始化字符数组,并且手动添加了空字符 '\0'
  3. str3:同样使用字符串字面量初始化字符数组,与 str1 类似,编译器会自动处理空字符。
字符指针形式
#include <stdio.h>

int main() {
    // 定义一个字符指针指向字符串常量
    char *str = "Hello, World!";
    printf("%s\n", str);

    return 0;
}

这里的 str 是一个字符指针,它指向了一个字符串常量。需要注意的是,字符串常量存储在只读内存区域,不能通过指针去修改它。

 字符数组的存储方式和整型数组在存储上的区别
  • 第一处 len = 5data 数组初始化有 5 个元素,sizeof(data) 是数组总字节数,sizeof(data[0]) 是单个元素字节数,相除得到元素个数 5
  • 第二处 len = 6cdata2 存储字符串 "hello",编译器自动添加结束符 '\0',实际元素为 'h''e''l''l''o''\0',共 6 个,计算得 6
  • 第三处 len = 6cdata 数组定义大小为 6sizeof(cdata)/sizeof(cdata[0]) 直接返回定义的数组大小 6

输出:

len = 5  
len = 6  
len = 6  

  字符数组的存储方式多了结束标志‘\0’


2. 字符串的输入输出

输出字符串

使用 printf 函数输出字符串:

使用 puts 函数输出字符串:

输入(获取)字符串

使用 scanf 函数输入字符串:

使用 gets 函数输入字符串:

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

int main()
{
	char *p="diqiqzhangzifuchuan";
	char str[128]={'\0'};
	
	puts(p);//输出字符串
	printf("%s\n",p);//输出字符串
	
	puts("请输入字符串");
	//scanf("%s",str);获取字符串
	//gets(str);//获取字符串

	//strcpy(str,p);
	strncpy(str,p,6);
		puts(str);
	return 0;
}

不过要注意,scanf 遇到空格就会停止读取,若想读取包含空格的字符串,可以使用 fgets 函数:

#include <stdio.h>

int main() {
    char str[100];
    printf("请输入一个字符串: ");
    fgets(str, sizeof(str), stdin);
    printf("你输入的字符串是: %s", str);
    return 0;
}

 stdin 用于标识输入数据的来源,程序通过它读取外部输入内容。当使用 scanffgetsgetchar 等输入函数时,若未指定其他输入流,默认从 stdin 读取数据,即接收用户通过键盘输入的内容。


 1. 使用 malloc 函数动态开辟字符串

函数原型  void *malloc(size_t size)

size:表示每个元素的大小(以字节为单位)。

步骤分析

  1. 明确字符串长度:要知道需要存储的字符串大概有多长,并且要额外预留 1 个字节用于存放字符串结束符 '\0'
  2. 调用 malloc 函数:根据确定的长度调用 malloc 函数分配内存。
  3. 检查分配结果:查看 malloc 函数的返回值是否为 NULL,若为 NULL 则表示内存分配失败。
  4. 使用字符串:把字符串内容复制到分配的内存中。
  5. 释放内存:使用完字符串后,调用 free 函数释放之前分配的内存,防止出现内存泄漏。

malloc 函数用于在堆内存中分配指定大小的连续内存空间。以下是使用 malloc 动态开辟字符串的示例:

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

int main() {
    int length = 20;
    // 使用 malloc 动态分配内存
    char *str = (char *)malloc((length + 1) * sizeof(char));
    if (str == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    // 复制字符串到分配的内存中
    strcpy(str, "Hello, World!");
    printf("字符串: %s\n", str);
    // 释放内存
    free(str);
    return 0;
}
代码解释:
  • malloc((length + 1) * sizeof(char)):分配 length + 1 个字符大小的内存空间,多出来的 1 个字符用于存储字符串结束符 '\0'
  • strcpy(str, "Hello, World!"):将字符串 "Hello, World!" 复制到分配的内存中。
  • free(str):释放之前分配的内存,避免内存泄漏。
2. 使用 calloc 函数动态开辟字符串

函数原型 void* calloc(size_t num, size_t size);

  • num:表示要分配的元素数量。
  • size:表示每个元素的大小(以字节为单位)。
  • 函数返回一个指向分配内存起始位置的指针,若分配失败则返回NULL

使用calloc动态开辟字符串的步骤

  1. 确定字符串长度:先明确要存储的字符串大概需要多大的空间,然后加上 1 个字节用于存储字符串结束符'\0'
  2. 调用calloc函数:依据确定的长度调用calloc函数分配内存。
  3. 检查分配结果:查看calloc函数的返回值是否为NULL,若为NULL则表示内存分配失败。
  4. 使用字符串:将字符串内容复制到分配的内存中。
  5. 释放内存:使用完字符串后,调用free函数释放之前分配的内存,防止内存泄漏。

calloc 函数也用于动态分配内存,与 malloc 不同的是,calloc 会将分配的内存初始化为 0。示例如下:

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

int main() {
    int length = 20;
    // 使用 calloc 动态分配内存并初始化为 0
    char *str = (char *)calloc(length + 1, sizeof(char));
    if (str == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    // 复制字符串到分配的内存中
    strcpy(str, "Hello, C!");
    printf("字符串: %s\n", str);
    // 释放内存
    free(str);
    return 0;
}
代码解释:
  • calloc(length + 1, sizeof(char)):分配 length + 1 个字符大小的内存空间,并将其初始化为 0。
  • strcpy(str, "Hello, C!"):将字符串 "Hello, C!" 复制到分配的内存中。
  • free(str):释放之前分配的内存。
3. 使用 realloc 函数调整字符串内存大小

函数原型 void *realloc(void *ptr, size_t size)

使用步骤

  1. 分配初始内存:首先使用 malloc 或 calloc 分配初始的字符串内存。
  2. 使用 realloc 调整内存大小:当需要增加或减少字符串长度时,调用 realloc 函数。
  3. 检查 realloc 的返回值:如果返回 NULL,说明内存分配失败,需要进行相应的错误处理。
  4. 释放内存:使用完字符串后,使用 free 函数释放内存。

realloc 函数用于调整已经分配的内存块的大小。示例如下:

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

int main() {
    int initialLength = 10;
    // 初始分配内存
    char *str = (char *)malloc((initialLength + 1) * sizeof(char));
    if (str == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    strcpy(str, "Hello");
    // 需要更大的内存空间
    int newLength = 20;
    char *newStr = (char *)realloc(str, (newLength + 1) * sizeof(char));
    if (newStr == NULL) {
        printf("内存重新分配失败\n");
        free(str);
        return 1;
    }
    str = newStr;
    // 继续添加字符串
    strcat(str, ", World!");
    printf("字符串: %s\n", str);
    // 释放内存
    free(str);
    return 0;
}
代码解释:
  • malloc((initialLength + 1) * sizeof(char)):初始分配 initialLength + 1 个字符大小的内存空间。
  • realloc(str, (newLength + 1) * sizeof(char)):将之前分配的内存空间调整为 newLength + 1 个字符大小。
  • free(str):释放最终分配的内存。
3.free 
C 库函数 void free(void *ptr) 释放之前调用 calloc、malloc 或 realloc 所分配的内存空间。

函数原型

void free(void *ptr);
  • 参数ptr 是一个指向之前通过 callocmalloc 或 realloc 分配的内存块的指针。
  • 返回值:该函数没有返回值,其返回类型为 void

free 函数的主要功能是将之前动态分配的内存归还给操作系统,这样这块内存就可以被其他程序或者本程序后续的内存分配操作再次使用。这有助于避免内存泄漏问题,所谓内存泄漏,就是程序不断分配内存却不释放,最终导致可用内存越来越少。

释放 malloc 分配的内存

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

int main() {
    // 使用 malloc 分配内存
    int *arr = (int *)malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    // 使用分配的内存
    for (int i = 0; i < 5; i++) {
        arr[i] = i;
    }
    // 释放内存
    free(arr);
    return 0;
}

释放后指针置为 NULL:为了避免误操作,在释放内存后,建议将指针置为 NULL

int *ptr = (int *)malloc(sizeof(int));
free(ptr);
ptr = NULL;  // 释放内存后将指针置为 NULL
 4.memset

void *memset(void *str, int c, size_t n) 是 C 语言标准库 <string.h> 中的一个函数,用于将一段内存区域的每个字节都设置为指定的值。

函数原型

void *memset(void *str, int c, size_t n)
  • 返回值:返回指向 str 的指针,即指向被设置的内存块起始位置的指针。这样设计是为了方便进行链式操作,比如可以在调用 memset 之后紧接着进行其他操作。
  • 参数
    • str:指向要设置的内存块的指针。它是一个 void * 类型的通用指针,这意味着可以传入任意类型的指针,因为 void * 可以接收任何类型的指针。
    • c:要设置的值。虽然参数类型是 int,但实际上只会使用该整数的低 8 位(即一个字节)的值来进行设置。
    • n:要设置的字节数,类型为 size_tsize_t 是一个无符号整数类型,通常用于表示对象的大小。

功能描述

memset 函数的主要功能是将从 str 所指向的内存地址开始的连续 n 个字节,每个字节都设置为 c 的低 8 位所表示的值。

初始化字符数组
#include <stdio.h>
#include <string.h>

int main() {
    char str[10];
    // 将 str 数组的前 10 个字节都设置为 'A'
    memset(str, 'A', 10);
    for (int i = 0; i < 10; i++) {
        printf("%c ", str[i]);
    }
    printf("\n");
    return 0;
}

 


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

int main()
{
	char *p;
	p=(char*)malloc(1);
	*p='c';
	free(p);
	p=NULL;
	p=(char*)malloc(12);
	if(p==NULL){
		printf("malloc error\n");
		exit(-1);
		
	}
	memset(p,'\0',12);
	printf("扩容前地址:%x\n",p);
	int len =strlen("chenlicheng123456788888");
	int newLen=len-12+1;
	realloc(p,newLen);
	printf("扩容后地址:%x\n",p);
	strcpy(p,"chenlicheng123456788888");
	puts(p);
	puts("end");
	return 0;
	
}

 


网站公告

今日签到

点亮在社区的每一天
去签到