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;