如何在没有malloc的情况下使用交换功能?
我想创建没有malloc的void指针。但是通过交换值和使用void指针,我看不到不使用malloc的解决方案 有没有一种方法可以不使用malloc进行这种操作。我在考虑双指针,但这也不是解决方案 徖如何在没有malloc的情况下使用交换功能?,c,pointers,malloc,swap,C,Pointers,Malloc,Swap,我想创建没有malloc的void指针。但是通过交换值和使用void指针,我看不到不使用malloc的解决方案 有没有一种方法可以不使用malloc进行这种操作。我在考虑双指针,但这也不是解决方案 徖 #include <stdio.h> // Standard library functions for file input and output #include <stdlib.h> // Standard library used for memory alloca
#include <stdio.h> // Standard library functions for file input and output
#include <stdlib.h> // Standard library used for memory allocation, process control, and conversions
typedef unsigned char byte_t;
// Declaration of the function
void genericSwap(void *pdata1, void *pdata2, byte_t nBytes);
// Global variable
unsigned int dataFloat = 0; // this will help us as a flag to differentiate
// between a float or integer
int main() // main program
{
int sw; // integer value for switch
int a = 0, b = 0; // declaring integer a and b
char x = 0, y = 0; // declaring character x and y
float c = 0, d = 0; // declaring float c and d
for (;;) // infinite loop
{
printf("\nPlease enter your choice:\n'1' for integer value.\n'2' for "
"character value.\n'3' for float value.\n'0' for exit. \n : ");
scanf_s("%d", &sw); // choose the input for the switch function
switch (sw) // switch function
{
case 1: // case 1 for selecting integer operations
printf("\nPlease enter the values for a and b \n : ");
scanf_s("%d%d", &a, &b); // choose the input for the integer operation
printf("\nValues before swap\na=%d\tb=%d", a, b);
genericSwap(
&a, &b,
sizeof(int)); // calling the swap function with address of a and b
printf("\nValues after swap\na=%d\tb=%d", a,
b); // printing the swap values
break;
case 2: // case 2 for selecting character operations
printf("\nPlease enter the values for a and b \n : ");
scanf_s(" %c", &x);
scanf_s(" %c", &y);
printf("\nValues before swap\na= %c\tb= %c", x, y);
genericSwap(
&x, &y,
sizeof(char)); // calling the swap function with address of x and y
printf("\nValues after swap\na= %c\tb= %c", x, y);
break;
case 3: // case 3 for selecting float operations
dataFloat = 1; // indicate that the float operation has been selected
printf("\nPlease enter the values for a and b \n : ");
scanf_s("%f%f", &c, &d);
printf("\nValues before swap\na= %.2f\tb= %.2f", c, d);
genericSwap(
&c, &d,
sizeof(float)); // calling the swap function with address of c and d
printf("\nValues after swap\na= %.2f\tb= %.2f", c, d);
break;
case 0: // terminate the application
exit(1);
break;
default: // when no appropriate selection has been made
printf("\nYou have entered the wrong choice");
break;
}
}
}
// define function
void genericSwap(void *pdata1, void *pdata2, byte_t nBytes) {
void *temp = NULL; // setting void pointer temp to NULL
temp = malloc(nBytes); // allocating memory to void pointer
if (nBytes > 1) // if the size is more then 1 byte this means it is another
// value then a character
{
if (dataFloat == 1) // if dataFloat is equal to 1 then it is a float type
{
dataFloat = 0; // resetting dataFloat to 0
*((float *)temp) = *((float *)pdata1); // typecasting the pointer to float
*((float *)pdata1) = *((float *)pdata2);
*((float *)pdata2) = *((float *)temp);
} else {
*((int *)temp) = *((int *)pdata1); // typecasting the pointer to integer
*((int *)pdata1) = *((int *)pdata2);
*((int *)pdata2) = *((int *)temp);
}
} else {
*((char *)temp) = *((char *)pdata1); // typecasting the pointer to character
*((char *)pdata1) = *((char *)pdata2);
*((char *)pdata2) = *((char *)temp);
}
free(temp); // de-allocating memory
temp = NULL; // making the pointer temp to NULL
}
#包括//用于文件输入和输出的标准库函数
#包括//用于内存分配、进程控制和转换的标准库
typedef无符号字符字节;
//职能声明
void genericSwap(void*pdata1,void*pdata2,字节);
//全局变量
无符号int-dataFloat=0;//这将有助于我们作为一个标志来区分
//介于浮点或整数之间
int main()//主程序
{
int sw;//开关的整数值
int a=0,b=0;//声明整数a和b
字符x=0,y=0;//声明字符x和y
浮点c=0,d=0;//声明浮点c和d
for(;;)//无限循环
{
printf(“\n请输入您的选项:\n'1'表示整数值。\n'2'表示”
“字符值。\n'3'表示浮点值。\n'0'表示退出。\n:”;
scanf_s(“%d”,&sw);//选择开关功能的输入
开关(sw)//开关功能
{
案例1://选择整数运算的案例1
printf(“\n请输入a和b的值:”);
scanf_s(“%d%d”,&a和&b);//选择整数运算的输入
printf(“\n交换前的值\na=%d\tb=%d”,a,b);
通用软件(
&a、 &b,
sizeof(int));//调用地址为a和b的交换函数
printf(“\n交换后的值\na=%d\tb=%d”,a,
b) ;//打印交换值
打破
案例2://选择字符操作的案例2
printf(“\n请输入a和b的值:”);
扫描频率(“%c”和“&x”);
扫描频率(“%c”和“y”);
printf(“\n交换前的值\na=%c\tb=%c”,x,y);
通用软件(
&x、 &y,
sizeof(char));//调用地址为x和y的swap函数
printf(“\n交换后的值\na=%c\tb=%c”,x,y);
打破
案例3://选择浮动操作的案例3
dataFloat=1;//表示已选择浮点操作
printf(“\n请输入a和b的值:”);
扫描(“%f%f”、&c和&d);
printf(“\n交换前的值\na=%.2f\tb=%.2f”,c,d);
通用软件(
&c、 &d,
sizeof(float));//调用地址为c和d的交换函数
printf(“\n交换后的值\na=%.2f\tb=%.2f”,c,d);
打破
案例0://终止应用程序
出口(1);
打破
默认值://未进行适当选择时
printf(“\n您输入了错误的选项”);
打破
}
}
}
//定义函数
void genericSwap(void*pdata1,void*pdata2,字节){
void*temp=NULL;//将void指针temp设置为NULL
temp=malloc(nBytes);//为无效指针分配内存
if(nBytes>1)//如果大小大于1字节,则表示它是另一个字节
//然后是一个字符
{
if(dataFloat==1)//如果dataFloat等于1,则它是浮点类型
{
dataFloat=0;//将dataFloat重置为0
*((float*)temp)=*((float*)pdata1);//键入将指针转换为float
*((浮动*)pdata1)=*((浮动*)pdata2);
*((浮动*)pdata2)=*((浮动*)温度);
}否则{
*((int*)temp)=*((int*)pdata1);//类型转换指向整数的指针
*((int*)pdata1)=*((int*)pdata2);
*((int*)pdata2)=*((int*)温度);
}
}否则{
*((char*)temp)=*((char*)pdata1);//键入指向字符的指针
*((char*)pdata1)=*((char*)pdata2);
*((字符*)pdata2)=*((字符*)温度);
}
空闲(临时);//取消分配内存
temp=NULL;//将指针temp设置为NULL
}
如果体系结构能够处理对32位或64位数据的未对齐访问,那么编译器很可能会优化对memcpy的调用
Cortex-M0要求数据对齐,而编译器没有优化memcpy
您可以将缓冲区设置为更大(在本例中为64字节),编译器还将生成非常高效的代码:如果您确实不想分配动态内存,可以一次交换一个字节(或某个固定大小)。如果保证
nBytes
不会太大,另一个可能的选择是使用VLA(可变长度数组-例如,uint8_t tmpArray[nBytes];
)。这有点危险,可移植性也有点差。但请注意,作为完整性的一个选项。不要过度思考这个问题。您正在交换两个内存区域(最好大小相同,这样才能工作)。使用两个无符号字符指针,同时迭代两个区域,一路上交换八位字节。更难的是:一旦您确定这是某种程度上,某种方式,您错误地认为需要修复的性能瓶颈的核心,请计算机器字边界,以便更有效地交换所讨论的大部分区域的数据。I如果它可用,您可以使用alloca
在堆栈上分配内存。上面的代码不关心别名。这是一个值得注意的问题:即使是在循环和单字符交换时编写基本代码,人们也可能会惊讶地发现@WhozCraig的效果有多好。@WhozCraig它远没有效率。我们不希望每个字节都有分支来刷新管道e等@WhozCraig查看我的答案中的第二个示例:@WhozCraig-clang如果将您在内部循环中使用的对memcpy
的三个调用内联,则会更好。
void *genericSwap(void *a, void *b, size_t size)
{
uint64_t tmp; //max size depends on the hardware architecture
unsigned char *ua = a;
unsigned char *ub = b;
if(a && b)
{
while(size >= sizeof(tmp))
{
memcpy(&tmp, ua, sizeof(tmp));
memcpy(ua, ub, sizeof(tmp));
memcpy(ub, &tmp, sizeof(tmp));
ua += sizeof(tmp);
ub += sizeof(tmp);
size -= sizeof(tmp);
}
while(size--)
{
unsigned char tmp = *ua;
*ua++ = *ub;
*ub++ = tmp;
}
}
return a;
}