FizzBuzz

本文介绍了C语言中动态内存管理的基本操作,包括malloc、calloc、strdup、snprintf和sprintf等函数的使用方法及注意事项,同时通过示例代码展示了如何在实际编程中合理运用这些函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实际运行时头文件:vs2013

#if _MSC_VER
#define snprintf _snprintf
#endif
#pragma warning(disable: 4996)


方法一:

char** fizzBuzz(int n, int* returnSize) {
	int i;
	char **ret;
	char *buf;
	ret = (char **)calloc(1, n * sizeof(char **));//两次分配内存
	for (i = 0; i < n; i++)
		ret[i] = (char *)calloc(1, 16 * sizeof(char *));//内存
	for (i = 0; i < n; i++) {
		if ((i + 1) % 15 == 0) {
			ret[i] = strdup("FizzBuzz");
		}
		else if ((i + 1) % 3 == 0) {
			ret[i] = strdup("Fizz");
		}
		else if ((i + 1) % 5 == 0) {
			ret[i] = strdup("Buzz");
		}
		else {
			snprintf(ret[i], 31, "%d", i + 1);
		}
	}


	*returnSize = n;
	return ret;
}

学会三个知识点:

一:malloc和calloc

它们都是动态分配内存,先看看它们的原型:

void *malloc( size_t size ); //分配的大小

void *calloc( size_t numElements, size_t sizeOfElement ); // 分配元素的个数和每个元素的大小

共同点就是:它们返回的是 void * 类型,也就是说如果我们要为int或者其他类型的数据分配空间必须显式强制转换

不同点是:用malloc分配存储空间时,必须由我们计算需要的字节数。如果想要分配5个int型的空间,那就是说需要5*sizeof(int)的内存空间:

int * ip_a;
ip_a = (int*)malloc( sizeof (int) * 5 );

而用calloc就不需要这么计算了,直接:
ip_a = ( int* )calloc( 5, sizeof(int) );这样,就分配了相应的空间,而他们之间最大的区别就是:用malloc只分配空间不初始化,也就是依然保留着这段内存里的数据,而calloc则进行了初始化,calloc分配的空间全部初始化为0,这样就避免了可能的一些数据错误。

二:strdup函数

原型:
extern char *strdup(char *s);
头文件:string.h
说明:
功 能: 将串拷贝到新建的位置处
strdup()在内部调用了malloc()为变量分配内存,不需要使用返回的字符串时,需要用free()释放相应的内存空间,否则会造成内存泄漏。
返回值:编辑
返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值。

三:snprintf函数

函数原型:int snprintf(char *str, size_t size, const char *format, ...)

功能:
将可变个参数(...)按照format格式化成字符串,然后将其复制到str中
(1) 如果格式化后的字符串长度 < size,则将此字符串全部复制到str中,并给其后添加一个字符串结束符('\0');
(2) 如果格式化后的字符串长度 >= size,则只将其中的(size-1)个字符复制到str中,并给其后添加一个字符串结束符('\0'),返回值为欲写入的字符串长度

方法二:

char** fizzBuzz(int n, int* returnSize) {
	*returnSize = n;
	char buf[11];
	char** p = (char**)malloc(sizeof(char*)*n);
	int i = 0;
	for (i = 0; i<n; i++)
	{
		if ((i+1)%15==0)
		{
			sprintf(buf, "%s", "FizzBuzz");
		}
		else if ((i + 1) % 3 == 0){
			sprintf(buf, "%s", "Fizz");
		}
		else if ((i + 1) % 5 == 0){
			sprintf(buf, "%s", "Buzz");
		}
		else{
			sprintf(buf, "%d", i + 1);
		}
		p[i] =(char *) malloc(sizeof(buf));//也要分配内存
		memcpy(p[i], buf, strlen(buf) + 1);
		//memset(buf,0, 11);
	}

	return p;
}
学会一个知识点:

sprintf函数

功能
把格式化的数据写入某个字符串缓冲区。
头文件
stdio.h
原型
int sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]...:可选参数,可以是任何类型的数据。
返回值
返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。

sprintf和snprintf区别:

snprintf最多从源串中复制size-1 个字符到目标串中,然后再后面加一个\0,sprintf没有这样的限制,使用snprintf更安全。
sprintf使用注意事项
(1)多个字符串连接,sprintf(s,"%.Ms %.Ns",a1,a2);其中M N 是正整数,分别指定复制a1中的M个字符,a2中N个字符输出到s中
(2)一定要申请较大的数组空间,避免出现堆栈的溢出,破坏堆栈
snprintf使用注意事项
(1)snprintf最多从源串中复制size-1 个字符到目标串中,返回值是源串字符的个数,而不是复制字符的个数
snprintf(buf,sizeof(buf),......)

方法三:

char** fizzBuzz(int n, int* returnSize) {
	char **s;
	s = (char **)malloc(n * sizeof(char*));
	char temp[1024];//足够大内存
	for (int i = 0; i < n; i++){
		if ((i + 1) % 3 && (i + 1) % 5){
			sprintf(temp, "%d", i + 1);
			s[i] = (char *)malloc(strlen(temp) + 1);
			strcpy(s[i], temp);
		}
		if ((i + 1) % 15 == 0){
			s[i] = (char *)malloc(strlen("FizzBuzz") + 1);
			strcpy(s[i], "FizzBuzz");
		}
		else if ((i + 1) % 3 == 0){
			s[i] = (char *)malloc(strlen("Fizz") + 1);
			strcpy(s[i], "Fizz");
		}
		else if ((i + 1) % 5 == 0){
			s[i] = (char *)malloc(strlen("Buzz") + 1);
			strcpy(s[i], "Buzz");
		}
	}
	*returnSize = n;
	return s;
}
运行时间一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值