类型系统
- 动态类型
- 静态类型
- 强类型、弱类型
编译时就知道变量类型的是静态类型;运行时才知道一个变量类型的叫做动态类型。 不允许隐式转换的是强类型,允许隐式转换的是弱类型。
类型本质
屏蔽掉数据和操作数据的细节,让算法更通用,让编程者更多关注算法的结构,而不是在算法中处理不同的数据类型
- 类型是对内存的一种抽象。不同的类型,会有不同的内存布局和内存分配的策略。
- 不同的类型,有不同的操作。所以,对于特定的类型,也有特定的一组操作。
优势
- 程序语言的安全性 强类型语言
- 利于编译器的优化
- 代码的可读性
- 抽象化
泛型目标
- 算法的泛型
- 类型的泛型
- 数据结构(数据容器)的泛型
C语言
设计目标提供一种能以简易的方式编译、处理低层内存、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
伟大之处——使用C语言的程序员在高级语言的特性至上还能简单地做任何底层的微观控制。C语言是高级语言中的汇编语言。
设计理念
- 相信程序员,不会阻止程序员做任何底层的事。
- 保持语言的最小和最简的特性
- 保证C语言的最快的运行速度,哪怕牺牲移植性。
优点
- 静态弱类型语言,使用变量时需要声明变量类型,但是类型之间支持隐式转换。
- 不同的变量类型可以用结构体组合在一起,以此来声明新的数据类型。
- C语言可以用typedef关键字来定义类型的别名,以此来达到变量类型的抽象。
- C语言传递参数一般是以值传递,也可以传递指针;
- 通过指针,C语言可以容易地对内存进行低级控制,然后这加大了编程难度。
- 一个有结构化程序设计、具有变量作用于以及递归功能的过程式语言。
- 编译预处理让C语言的编译更具有弹性,比如跨平台。
缺点
- 面向过程和底层,不适合复杂业务开发。
1. void *
内存复制
arduino
复制代码
void swap(void* x, void* y, size_t size)
{
char tmp[size];
memcpy(tmp, y, size);
memcpy(y, x, size);
memcpy(x, tmp, size);
}
2. 宏定义Define
字符串替换
坑:
- 代码膨胀,编译出可执行文件比较大。
- 字符串替换导致入参执行多次
scss
复制代码
#define swap(x, y, size) {\
char temp[size]; \
memcpy(temp, &y, size); \
memcpy(&y, &x, size); \
memcpy(&x, temp, size); \
}
复杂demo:
Search函数
arduino
复制代码
int search(int* a, size_t size, int target) {
for(int i=0; i<size; i++) {
if (a[i] == target) {
return i;
}
}
return -1;
}
arduino
复制代码
int search(void* a, size_t size, void* target,
size_t elem_size, int(*cmpFn)(void*, void*) )
{
for(int i=0; i<size; i++) {
// why not use memcmp()
// use unsigned char * to calculate the address
if ( cmpFn ((unsigned char *)a + elem_size * i, target) == 0 ) {
return i;
}
}
return -1;
}