内存区域 全局变量 线程 插值查找 位域 栈的实现
栈区可以修改默认大小配置:
栈区默认的大小是1M,在vs2013中可以修改。

堆区和栈区的地址区别:
栈是连续的,向上增长,地址越来越小。类似数组。
堆是链接的,向下增长,地址越来越大。类似链表。
栈区 高地址到低地址
堆区 低地址到高地址

#include <stdio.h>#include <stdlib.h>int main(){int a = 1, b = 2;printf("%p,%p\n", &a, &b); //a的地址大于b的地址char *p1 = malloc(1);char *p2 = malloc(1);printf("%p,%p\n", &p1, &p2);//p1的地址大于p2的地址printf("%p,%p\n", p1, p2);//p1指向的地址小于p2指向的地址return 0;}

代码区:只读不可写
int a = 45; //a在栈上 45在寄存器
常量字符串在代码区:
char *p = "calc"; // p在栈上, “calc”在代码区
char *p = "liuwei"; //指针只存了地址printf("%d,%d\n",sizeof(p),sizeof("liuwei")); // 4 7
全局变量的注意事项:
1. 全局变量前一定不能加上 auto 不能放在栈上。
2. 全局变量具有声明和定义的区别。
int a;int a;
int a;
这种是可以通过编译的。因为三个都属于声明。 int a;这样没有赋值的属于声明。
不过局部内,这样就不可以了,局部变量没有声明和定义的区别。
#include <stdio.h>int a;int a;int a;int main(){printf("%d\n", a); //结果输出0.return 0;}
3. 全局变量如果只有声明,没有定义,会自动初始化0。因为是在Bss段。
4. 全局如果 int a = 1; int a = 2;会出现多重定义问题。有赋值运算符的属于定义。
5. 不同文件的全局变量:
全局变量可以跨文件使用、同一个工程,不同源文件,不能出现两个同名变量的定义 。
当两个文件同时使用一个全局变量时,需要在另一个文件内,先extern声明,再使用。
因此头文件最好只声明,不要定义,免得包含多次,就会出现多定义。当然可以用ifdef避免
函数默认是全局函数:
函数默认都是全局函数,跨文件的函数可以直接使用。
a.c
#include <stdio.h>int main(){gogo();return 0;}
b.c
#include <stdio.h>void gogo(){printf("gogo\n");}
可以直接打印出gogo,虽然在a.c里没有函数声明,因为函数默认就是全局的
但是本文件内部调用函数之前声明,或者在前面定义
#include <stdio.h>void gogo();//函数声明int main(){gogo();}void gogo(){printf("gogo\n");}
线程:
#include <process.h> //包含线程头文件
_beginthread();//开启一个线程
#include <stdio.h>#include <windows.h>#include <process.h>void runMsg(void *p){MessageBoxA(0, "hello", "world", 0);}void main(){_beginthread(runMsg, 0, NULL);_beginthread(runMsg, 0, NULL);_beginthread(runMsg, 0, NULL);getchar();//不加getchar()不行,因为主线程结束了,其他线程都挂掉了}
线程传递参数:
#include <stdio.h>#include <windows.h>#include <process.h>void run(void *p){MessageBoxA(0, "hello", p, 0);}int main(){_beginthread(run, 0, "ABC");_beginthread(run, 0, "CDE");_beginthread(run, 0, "XYZ");getchar();return 0;}
如果想传递多个参数,可以传递结构体的指针
#include <stdio.h>#include <windows.h>#include <process.h>struct STU{char name[10];char title[10];};struct STU stu[3] = { {"hello","world"}, {"fuck","shit"}, {"apple","pear"} };void run(void *p){struct STU *tmp = (struct STU *)p;MessageBoxA(0, tmp->name, tmp->title, 0);}int main(){for (int i = 0; i < 3;i++){_beginthread(run, 0, &stu[i]);}getchar();return 0;}

位域实战代码:
通过位域实现输入一个数,输出其补码
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>typedef struct{unsigned char ch1 : 1;unsigned char ch2 : 1;unsigned char ch3 : 1;unsigned char ch4 : 1;unsigned char ch5 : 1;unsigned char ch6 : 1;unsigned char ch7 : 1;unsigned char ch8 : 1;}bit;int main(){int num;scanf("%d", &num);bit *mybit =#for (int i = 3; i >= 0; i--) //地址要从高字节打到低字节{printf("%d%d%d%d %d%d%d%d ",mybit[i].ch8, mybit[i].ch7, mybit[i].ch6, mybit[i].ch5,mybit[i].ch4, mybit[i].ch3, mybit[i].ch2, mybit[i].ch1);}return 0;}

插值查找(二分查找升级版,注意只能在有序并且分布均匀的情况下查找)
#include <stdio.h>int find(int *a, int n, int key){int low = 0, high = n - 1;int mid, count = 0;while (low <= high){printf("查找第%d次\n", ++count);//mid = (low + high) / 2; 二分查找bug版本//mid = low + (high - low) / 2; 二分查找正确版mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]);//插值查找if (a[mid] == key)return mid;else if (a[mid] < key)low = mid + 1;elsehigh = mid - 1;}return -1;}int main(){int i;int a[1024 * 100];for (i = 0; i < 1024 * 100; i++)a[i] = i;int pos = find(a, 1024 * 100, 102);if (pos != -1)printf("%d %d\n", pos, a[pos]);elseprintf("没有找到\n");}
注:二分查找的一个bug
见:排序算法
数据结构栈,实现递归:
栈的数据结构实现:
#include <stdio.h>#include <string.h>#define N 50struct stack{int top;int data[N];};void init_stack(struct stack *p){p->top = -1;memset(p->data, 0, sizeof(int)*N);}int is_empty(struct stack *p){if (p->top == -1)return 1;elsereturn 0;}int is_full(struct stack *p){if (p->top == N - 1)return 1;elsereturn 0;}void push_stack(struct stack *p, int key){if (is_full(p))return;p->top++;p->data[p->top] = key;}int pop_stack(struct stack *p){if (is_empty(p))return -1;int data = p->data[p->top];p->top--;return data;}int main(){struct stack mystack;init_stack(&mystack);int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int i;for (i = 0; i < 10; i++){push_stack(&mystack, a[i]);}while (!is_empty(&mystack)){printf("%d\n", pop_stack(&mystack));}return 0;}
递归打印一个整数的二进制
#include <stdio.h>void bin(int num){if (num == 0)return;bin(num / 2);printf("%d\n", num % 2); // 1 0 1 0}int main(){bin(10);return 0;}
用上面的栈数据结构实现以上的递归。
int main(){struct stack mystack;init_stack(&mystack);int num = 10;while (num){push_stack(&mystack, num % 2);num /= 2;}while (!is_empty(&mystack)){printf("%d\n", pop_stack(&mystack));}return 0;}

浙公网安备 33010602011771号