c/c++整理(二)

1.动态内存分配

malloc free 和 new delete区别

new/delete是c++运算符

malloc/free函数是库函数而不是运算符,不能执行构造函数和析构,因此只能使用new/delete运算符。

c标准内存分配函数有malloc, calloc, realloc,free等

(类型 *)malloc(size):分配size字节的连续空间,返回首地址,此时内存中的值没有初始化,是一个随机数。

(类型 *)calloc(n, size): 分配n*size个字节连续空间,返回首地址,此时内存的值都被初始化为0。

(类型 *)realloc(*ptr, size):将ptr内存大小增大到size,新增加的内存块没有初始化。

free调用形式 free(void *ptr):释放ptr所指向的内存空间。

不用内置函数将数字转为字符串

void int_to_str(int n, char *str)
{
	char buf[10] = "";
	int i = 0, len = 0;
	int temp = n < 0? -n : n;

	if ( str == NULL)
	{
		return ;
	}
	while (temp)
	{
		buf[i++] = temp % 10 + '0';
		temp /= 10;
	}
	len = n < 0 ? ++i: i;
	str[i]  = 0;
	while (1)
	{
		i--;
		if (buf[len - i - 1] == 0)
		{
			break;
		}
		str[i] = buf[len  - i - 1];
	}
	if (i == 0)
	{
		str[i] = '-'
	}
	
	return ;
}

2.字符串

将任意类型的数字转换为字符串

itoa():将整型值转为字符串

ltoa():长征性

ultoa():无符号长整型

gcvt():浮点型转换为字符串,四舍五入

ecvt():双精度,转换结果不包含十进制小数点

fcvt():指定位数为转换精度,其余同ecvt()

字符串转换为数字

atof():转成双精度

atoi():整型

atol():长整型

不用内置函数将字符串转为数字

int str_to_int(const char *str)
{
	int temp = 0;
	const char *ptr = str;
	if (*str == '-' || *str == '+')
	{
		str++;
	}
	while (*str != 0)
	{
		if ((*str < '0') ||(*str > '9'))
		{
			break;
		}
		temp = temp * 10 + (*str - '0');
		str++;
	}
	if (*ptr == '-')
	{
		temp = -temp;
	}
	
	return temp;
}

编程实现strcpy

char * my_strcpy(char * strDest, const char * strSrc)
{
	if (strDest == NULL || strSrc == NULL)
	{
		return NULL;
	}
	char  *strDestCopy = strDest;
	while ((*strDest++ = *strSrc++) != '\0');
	return strDestCopy;
}

编程实现memcpy

void* my_memcpy(void *memTo, void *memFrom, size_t size)
{
	assert((memTo != NULL) && (memFrom != NULL));
	char *tempFrom = (char *)memFrom;
	char *tempTo = (char *)memTo;
	while (size-- > 0)
	{
		*tempTo++ = *tempFrom++
	}
	return memTo;
}

实现字符串中子串查找

const char *strstr(const char * src, const char *sub)
{
	const char *bp, *sp;
	if (src ==	NULL || sub == NULL)
	{
		return src;
	}
	while (*src)
	{
		bp = src;
		sp = sub;
		do
		{
			if (!*sp)
			{
				return src
			}
		}
		while (*bp ++ == *sp++);
		src += 1;
	}
	return NULL;
}

编程实现字符串中各单词的反转(先进行整体串的反转,再对所有单词反转)

#include <stdio.h>
void swap(char *a, char *b)
{
    char temp = *a;
    *a = *b;
    *b = temp;
}
void revert_str(char *src)
{
	char *start = src, *end = src, *ptr = src;
	while (*ptr++ != '\0');
	end = ptr - 2;
	while (start < end)
	{
		swap(start++, end--);
	}
	start = src;
	end = ptr - 2;
	ptr = start;
	while (*ptr++ != '\0')
	{
		if (*ptr == ' ' || *ptr == '\0' )
		{
			end = ptr - 1;
			while (start < end)
			{
				swap(start++, end--);
			}
			start = end = ptr  + 1;
		}
	}
}

int main()
{
	char a[] = "i    love    you";
	printf("%s\n",a);
	revert_str(a);
	printf("%s",a);
	getch();
	return 0;
}

回文串判断

int is_rev_str(char *str)
{
	int i, len, found = 1;
	if (str == NULL)
	{
		return -1;
	}
	len = strlen(str);
	for (i = 0; i < len / 2; i++)
	{
		if (*(str + i) != *(str + len - i - 1))
		{
			found = 0;
			break;
		}
	}
	return found;
}

编程实现strcmp

int my_strcmp(const char *src, congst char *dst)
{
	int ret = 0;
	while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
	{
		++src;
		++dst;
	}
	if (ret < 0)
	{
		ret = -1;
	}
	else if (ret > 0)
	{
		ret = 1;
	}
	return ret;
}

查找两字符串中最大公共子串

char *common_string(char *str1, char *str2)
{
	int i, j;
	char *shortstr, *longstr, *substr;
	if (str1 == NULL || str2 == NULL)
	{
		return NULL;
	}
	if (strlen(str1) <= strlen(str2))
	{
		shortstr = str1;
		longstr = str2;
	}
	else
	{
		shortstr = str2;
		longstr = str1;
	}
	if (strstr(longstr, shortstr) != NULL)
	{
		return shortstr;
	}
	substr = (char *)malloc(sizeof(char) * (strlen(shortstr) + 1))
	for (i = strlen(shortstr) - 1; i > 0; i--)
	{
		for (j = 0; j <= strlen(shortstr) - i; j++)
		{
			memcpy(substr, &short[j], i);
			substr[i] = '\0';
			if (strstr(longstr, substr) != NULL)
			{
				return substr;
			}
		}
	}

}

编程实现转2进制

char *to_binary(long num)
{
	int i = 0;
	char *buffer, *temp;
	buffer = (char *)malloc(33);
	temp = buffer;
	for (i = 0; i ,< 32; i++)
	{
		temp[i] = num & (1 << (31 - i));
		temp[i] = temp[i]  >> (31 - i);
		temp[i] = (temp[i] == 0) ? '0' : '1';
	}
	buff[32] = '\0';
	return buffer;
}

编程实现转16进制

char *to_heximal(long num)
{
	int i = 0;
	char *buffer = (char *)malloc(11);
	char *temp;
	buffer[0] = '0';
	buffer[1] = 'x';
	buffer[10] = '\0';
	temp = buffer + 2;
	for (i  = 0; i < 8; i++)
	{
		temp[i] = (char)(num << 4 * i  >> 28);
		temp[i] = temp[i] >= 0 ? temp[i]  : temp[i]  + 16;
		temp[i] = temp[i] < 0 ? temp[i] + 48 : temp[i]  + 55;
	}
	return buffer;
}

3.嵌入式编程

1.#define

#define SECONDS_PER_YEAR (60*60*24*365)UL

UL告诉编译器是无符号长整型。

2.访问特定的内存

例:一个整型变量的绝对地址0x66aa, 将其值身为0x1234

int *ptr;

ptr = (int *)0x66aa;

*ptr = 0x1234;

3.中断服务支持

_interrupt double compute_area(double radius)
{
	double area = PI * radius * radius;
	printf("area = %f", area);
	return area;
}

ISR 不能有返回值。

ISR不能传递参数。

ISR应该短而有效率,不应该做浮点运算。

printf()经常出现重入和性能问题。

4.c中关键字volatile

定义为volatile的变量可能有意想不到的改变,这样,编译器就不会去假设这个变量的值。优化器在用到volatile变量时必须小心重新读取该变量的值,而不是使用保存在寄存器里的备份。下面是使用volatile变量的三个例子:

    • 并行设备的硬件寄存器(如:状态寄存器)。
    • 一个中断服务子程序中会访问到的非自动变量。
    • 多线程应用中被几个任务共享的变量。

5.判断处理器使用的是大端还是小端

int checkCPU()
{
	union w
	{
		int a;
		char b;
	} c;
	c.a = 1;
	return c.b == 1;
}

联合体存放顺序是所有成员从地地址开始存放,利用该特性,得知大小端方式。返回0是大端模式。

6.考虑处理器字长

unsigned int zero = 0;

unsigned int compzero = 0xffff;

第二句错误,对于布什16位处理器来说不正确,改为unsigned int compzero =~0;

原文地址:https://www.cnblogs.com/seebro/p/2529364.html