| 数据类型 | 16位平台 | 32位平台 | 64位平台 |
|---|---|---|---|
| char | 1 字节 | 1 字节 | 1 字节 |
| pointer | 2 字节 | 4 字节 | 8 字节 |
| short | 2 字节 | 2 字节 | 2 字节 |
| int | 2 字节 | 4 字节 | 4 字节 |
| float | 4 字节 | 4 字节 | 4 字节 |
| double | 8 字节 | 8 字节 | 8 字节 |
| long | 4 字节 | 4 字节 | 8 字节 |
| long long | 8 字节 | 8 字节 | 8 字节 |
volatile 指出变量是随时可能发生变化的,每次使用它的时候必须从变量的地址中读取,因而编译器生成的汇编代码会重新从变量的地址读取数据。
int (*fun)(int *a); int (*fun[10])(int *data, int size); 使用方法:
int (*sort_fun[5])(int *data, int size) = { quick_sort, /* 快速排序 */ insert_sort, /* 插入排序 */ bubble_sort, /* 冒泡排序 */ heap_sort, /* 堆排序 */ selection_sort /* 选择排序 */ }; // 或者 sort_fun[0] = quick_sort; sort_fun[1] = insert_sort; int *a[10]; /* a为指向含10个元素的一维数组的指针变量, * ()优先级高,说明a是一个指针,指向一个整型的一维数组. * a+1时,a要跨过10个整型数据的长度 */ int (*a)[10]; int **a; 定义一个常量,声明的同时必须进行初始化。一旦声明,这个值将不能被改变。
const int constInt = 10; //正确 constInt = 20; //错误,常量值不可被改变 const int constInt3; //错误,未被初始化 指向常量的指针,不能用于改变其所指向的对象的值。
const int i = 5; const int i2 = 10; const int* pInt = &i; //正确,指向一个const int对象,即i的地址 //*pInt = 10; //错误,不能改变其所指缶的对象 pInt = &i2; //正确,可以改变pInt指针本身的值,此时pInt指向的是i2的地址 const int* p2 = new int(8); //正确,指向一个new出来的对象的地址 delete p2; //正确 //int* pInt = &i; //错误,i是const int类型,类型不匹配,不能将const int * 初始化为int * int nValue = 15; const int * pConstInt = &nValue; //正确,可以把int *赋给const int *,但是pConstInt不能改变其所指向对象的值,即nValue *pConstInt = 40; //错误,不能改变其所指向对象的值 指针本身就是一种对象,把指针定义为常量就是常量指针,也就是int* const的类型,也可以写成int *const,声明时必须初始化。
int nValue = 10; int* const p = &nValue; int *const p2 = &nValue; //const int* 指针指向的对象不可以改变,但指针本身的值可以改变;int* const 指针本身的值不可改变,但其指向的对象可以改变。 int nValue1 = 10; int nValue2 = 20; int* const constPoint = &nValue1; //constPoint = & nValue2; //错误,不能改变constPoint本身的值 *constPoint = 40; //正确,可以改变constPoint所指向的对象,此时nValue1 = 40 const int nConstValue1 = 5; const int nConstValue2 = 15; const int* pPoint = &nConstValue1; //*pPoint = 55; //错误,不能改变pPoint所指向对象的值 pPoint = &nConstValue2; //正确,可以改变pPoint指针本身的值,此时pPoint邦定的是nConstValue2对象,即pPoint为nConstValue2的地址 const int* const 是一个指向常量对象的常量指针,即不可以改变指针本身的值,也不可以改变指针指向的对象。
const int nConstValue1 = 5; const int nConstValue2 = 15; const int* const pPoint = &nConstValue1; //*pPoint = 55; //错误,不能改变pPoint所指向对象的值 //pPoint = &nConstValue2; //错误,不能改变pPoint本身的值 char * const cp; // cp is a const pointer to char const char * p; // p is a pointer to const char; char const * p; // 同上,因为C++里面没有const*的运算符,所以const只能属于前面的类型。 结论:
char * const cp // 定义一个指向字符的指针常数,即const指针 const char* p // 定义一个指向字符常数的指针 char const* p // 等同于const char* p const char ** // 是一个指向指针的指针,那个指针又指向一个字符串常量。 char ** // 也是一个指向指针的指针,那个指针又指向一个字符串变量。 | 符号位 | 指数位 | 尾数部分 |
| 1 bits | 8 bits | 23 bits |
| 符号位 | 指数位 | 尾数部分 |
| 1 bits | 11 bits | 52 bits |
#include int main() { int i = 43; printf("%d\n", printf("%d", printf("%d", i))); return 0; } 输出:4321
printf返回值是输出字符的个数(不包括字符串结尾\x00)
#include int main() { enum color{ RED, BLUE, GREEN = -2, YELLOW, PINK }; printf("%d %d\n", BLUE, PINK); return 0; } 输出:1 0
enum默认是从0开始的,所以RED = 0, BLUE = 1, GREEN = -2, YELLOW = -1, PINK = 0;
#include "stdarg.h" char buf[512] = {0}; int func(const char *fmt, ...) { va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); } union data { int a; char b; }; struct def { union data mine; }; struct def endian; int main(int argc, char **argv) { endian.mine.a = 0x12345678; printf("%02X\n", endian.mine.b); return 0; } /*打印 78 说明是小端, 12 说明是大端 */ //单链表的初始化,建立,插入,查找,删除。// //Author:Wang Yong // //Date: 2010.8.19 // #include #include typedef int ElemType; //定义结点类型 typedef struct Node { ElemType data; //单链表中的数据域 struct Node *next; //单链表的指针域 }Node,*LinkedList; //单链表的初始化 LinkedList LinkedListInit() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请结点空间 if(L == NULL) //判断是否有足够的内存空间 printf("申请内存空间失败/n"); L->next = NULL; //将next设置为NULL,初始长度为0的单链表 } //单链表的建立1,头插法建立单链表 LinkedList LinkedListCreatH() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表 ElemType x; //x为链表数据域中的数据 while(scanf("%d",&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 p->next = L->next; //将结点插入到表头L-->|2|-->|1|-->NULL L->next = p; } return L; } //单链表的建立2,尾插法建立单链表 LinkedList LinkedListCreatT() { Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表 Node *r; r = L; //r始终指向终端结点,开始时指向头结点 ElemType x; //x为链表数据域中的数据 while(scanf("%d",&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 r->next = p; //将结点插入到表头L-->|1|-->|2|-->NULL r = p; } r->next = NULL; return L; } //单链表的插入,在链表的第i个位置插入x的元素 LinkedList LinkedListInsert(LinkedList L,int i,ElemType x) { Node *pre; //pre为前驱结点 pre = L; int tempi = 0; for (tempi = 1; tempi < i; tempi++) pre = pre->next; //查找第i个位置的前驱结点 Node *p; //插入的结点为p p = (Node *)malloc(sizeof(Node)); p->data = x; p->next = pre->next; pre->next = p; return L; } //单链表的删除,在链表中删除值为x的元素 LinkedList LinkedListDelete(LinkedList L,ElemType x) { Node *p,*pre; //pre为前驱结点,p为查找的结点。 p = L->next; while(p->data != x) //查找值为x的元素 { pre = p; p = p->next; } pre->next = p->next; //删除操作,将其前驱next指向其后继。 free(p); return L; } / int main() { LinkedList list,start; /* printf("请输入单链表的数据:"); list = LinkedListCreatH(); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); */ printf("请输入单链表的数据:"); list = LinkedListCreatT(); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); int i; ElemType x; printf("请输入插入数据的位置:"); scanf("%d",&i); printf("请输入插入数据的值:"); scanf("%d",&x); LinkedListInsert(list,i,x); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); printf("请输入要删除的元素的值:"); scanf("%d",&x); LinkedListDelete(list,x); for(start = list->next; start != NULL; start = start->next) printf("%d ",start->data); printf("/n"); return 0; } 排序算法有:
| 选择排序 | 快速排序 | 希尔排序 | 冒泡排序 | 插入排序 | 堆排序 | 归并排序 |
排序算法比较:

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
平均: O(n2) 最好: O(n2) 最坏:O(n2) O(1) 
/* 直接选择排序 */ void selection_sort(int n) { for (int i = 0; i < n - 1; i++) { int min = i; for (int j = i + 1; j < n; j++) { if (x[j] < x[min]) { min = j; } } if (min != i) { swap(x,i,min); } } } 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
平均:O(n2) 最好:O(n) 最坏:O(n2) O(1) 
/* 直接插入排序 */ void insertion_sort(int n) { for(int i = 1; i < n; i++) { int t = x[i]; int j; for (j = i; j > 0 && x[j-1] > t ; j--) { x[j] = x[j - 1]; } x[j] = t; } } 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
平均:O(n1.5) 最好:O(n) 最坏O(n2) O(1) /* 希尔排序 */ void shell_sort(int n) { for (int inc = n/3; inc >= 1; inc /= 3 ) { for (int i = inc; i < n; i++) { int t = x[i]; int j; for (j = i; j >= inc && x[j - inc] > t ; j -= inc) { x[j] = x[j - inc]; } x[j] = t; } } } 平均: O(n2) 最好: O(n) 最坏:O(n2) O(1) 
/* 冒泡排序 */ void bubble_sort(int n) { bool change = true; for (int i = n-1; i >= 1 && change; i--) { change = false; for (int j = 0; j < i; j++) { if(x[j] > x[j + 1]) { swap(x, j, j + 1); change = true; } } } } 快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。
快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)。
快速排序又是一种分而治之思想在排序算法上的典型应用。本质上来看,快速排序应该算是在冒泡排序基础上的递归分治法。
快速排序的名字起的是简单粗暴,因为一听到这个名字你就知道它存在的意义,就是快,而且效率高!它是处理大数据最快的排序算法之一了。虽然 Worst Case 的时间复杂度达到了 O(n²),但是人家就是优秀,在大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好,可是这是为什么呢,我也不知道。好在我的强迫症又犯了,查了 N 多资料终于在《算法艺术与信息学竞赛》上找到了满意的答案:
快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
平均: O(nlogn) 最好: O(nlogn) 最坏:O(n2) O(nlogn) 用于方法栈 
/* 快速排序 */ void quick_sort(int l, int u) { if (l >= u) return; int m = l; for (int i = l+1; i<= u; i++) { if(x[i] < x[l]) swap(x, ++m, i); } swap(x, l, m); quick_sort(l, m-1); quick_sort(m+1, u); } unsigned int RSHash(char* str, unsigned int len) { unsigned int b = 378551; unsigned int a = 63689; unsigned int hash = 0; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = hash * a + (*str); a = a * b; } return hash; } /* End Of RS Hash Function */ unsigned int JSHash(char* str, unsigned int len) { unsigned int hash = 1315423911; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash ^= ((hash << 5) + (*str) + (hash >> 2)); } return hash; } /* End Of JS Hash Function */ unsigned int ELFHash(char* str, unsigned int len) { unsigned int hash = 0; unsigned int x = 0; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = (hash << 4) + (*str); if((x = hash & 0xF0000000L) != 0) { hash ^= (x >> 24); } hash &= ~x; } return hash; } /* End Of ELF Hash Function */ unsigned int DJBHash(char* str, unsigned int len) { unsigned int hash = 5381; unsigned int i = 0; for(i = 0; i < len; str++, i++) { hash = ((hash << 5) + hash) + (*str); } return hash; } /* End Of DJB Hash Function */ 字符串 数字 布尔 对象 数组 undefined null
js只有一种数字类型
undefined:当声明的变量没有初始化的话,那这个变量的值就是undefined
null表示尚未存在的对象。在这里插入图片描述