C 提高第一天复习

内存四区,变量常量的本质,函数调用模型,栈开口方向,指针铁律1,指针是一种数据类型

C 提高学员标准:写一个标准的冒泡排序

选择法或者冒泡法排序

在一个函数内排序

通过函数调用的方式排序

数组做函数参数的技术盲点和推演 

#include 
#include 
#include 
int main(){ int i = 0; int j = 0; int tmp = 0; int a[] = {3,66,54,32,11,22,99,2334,32}; for (i = 0; i < sizeof(a) / sizeof(int); i++) { printf("%d ",a[i]); } printf("\n", a[i]); for (i = 0; i < sizeof(a) / sizeof(int); i++) { for (j = i+1; j < sizeof(a) / sizeof(int); j++) { if (a[i] > a[j]) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } } for (i = 0; i < sizeof(a) / sizeof(int); i++) { printf("%d ", a[i]); } printf("\n", a[i]); system("pause");}编译运行:3 66 54 32 11 22 99 2334 323 11 22 32 32 54 66 99 2334请按任意键继续. . .

冒泡程序,优化输出与排序 与 函数的数组参数问题

#include 
#include 
#include 
void printfArray(int array[], int len){ int i; for (i = 0; i < len; i++) { printf("%d ", array[i]); } printf("\n", array[i]);}//数组做函数的参数的退回问题,退回为一个指针//结论:把数组内存的首地址和有效长度传给被调用的函数//本质:函数中的数组形参,编译器会把它当成指针处理void sortArray(int array[], int len){ int i, j, tmp; for (i = 0; i 
 array[j]) { tmp = array[i]; array[i] = array[j]; array[j] = tmp; } } }}int main(){ int a[] = {3,66,54,32,11,22,99,2334,32}; int len = sizeof(a) / sizeof(int); printfArray(a, len); sortArray(a,len); printfArray(a, len); system("pause");}编译运行:3 66 54 32 11 22 99 2334 323 11 22 32 32 54 66 99 2334请按任意键继续. . .

数据类型概念:

“类型”是对数据的抽象 

类型相同的数据有相同的表示形式、存储格式以及相关的操作 

程序中使用的所有数据都必定属于某一种数据类型 

基本数据类型:typedef 数组与地址

#include 
#include 
#include 
struct teacher1{ char name[64]; int age;}Teacher1;//使用typedef,以后定义就是这样了 Teacher2 t2;typedef struct teacher2{ char name[64]; int age;}Teacher2;int main(){ int b[10]; printf("b:%d , b+1:%d \n", b, b + 1); printf("&b:%d, &b+1:%d \n", &b, &b + 1); // b 代表数组首元素的地址 // &b代表整个数组的地址 // &b+1代表跨过整个数组地址 struct teacher1 t1; Teacher1.age = 0; Teacher2 t2; typedef int u32; printf("u32 =%d \n",sizeof(u32)); system("pause");}编译运行:b:3603504 , b+1:3603508&b:3603504, &b+1:3603544u32 =4请按任意键继续. . .

数据类型的本质思考

思考数据类型和内存有关系吗?

C/C++为什么会引入数据类型?

数据类型的本质 

数据类型可理解为创建变量的模具(模子);是固定内存大小的别名。

数据类型的作用:编译器预算对象(变量)分配的内存空间大小

程序举例,如何求数据类型的大小  sizeof(int *)

请问:数据类型可以有别名吗?数据类型可以自定义吗?(typedef)

数据类型大小C程序:

#include 
#include 
int main(){ int a = 10; int b[10] ; printf("int a:%d \n", sizeof(a)); printf("int a:%d \n", sizeof(int *)); printf("int b:%d \n", sizeof(b)); printf("int b:%d \n", sizeof(b[0])); printf("int b:%d \n", sizeof(*b)); printf("hello.....\n"); return 0;} 编译运行:C:\Users\chunli>gcc main.c & aint a:4int a:4int b:40int b:4int b:4hello.....

常量的探讨:

#include 
#include 
#include 
char * getstr1(){ char *p = "1234"; return p;}char * getstr2(){ char *p = "5678"; return p;}int main(){ char *p1 = NULL; char *p2 = NULL; p1 = getstr1(); p2 = getstr2(); printf("%s,%s \n", p1, p2); printf("%d,%d \n", p1, p2); system("pause");}编译运行:1234,567814309464,14309644请按任意键继续. . .

改一改:

#include 
#include 
#include 
char * getstr1(){ char *p = "1234"; return p;}char * getstr2(){ char *p = "1234"; return p;}int main(){ char *p1 = NULL; char *p2 = NULL; p1 = getstr1(); p2 = getstr2(); printf("%s,%s \n", p1, p2); printf("%d,%d \n", p1, p2); system("pause");}编译运行:1234,12342054232,2054232请按任意键继续. .

堆栈变量,函数返回一个被析构的内存空间块

#include 
#include 
#include 
//堆char * getmem(int size){ char *p = NULL; p = (char *)malloc(size); return p;}//栈//return 不是把内存块返回出来,而是把首地址返回了char * getmem2(){ char p[20]; strcpy(p, "haha2 \n"); return p; //【危险!】p即将释放,但是地址返回去来了。}int main(){ char  *p = NULL; p = getmem(20); strcpy(p, "haha1 \n"); printf("%s",p); free(p); p = NULL; p = getmem2();//返回了一个被析构的数据块 printf("%s", p);//不应该这么做! system("pause");}编译运行:haha1haha2请按任意键继续. . .

栈的开口方向:

#include 
#include 
#include 
int main(){ int a; int b; printf("&a = %d \n", &a); printf("&b = %d \n", &b); system("pause");}编译运行:C:\Users\chunli>gcc -o main.exe main.c & main&a = 2686652&b = 2686648请按任意键继续. . .

数组基地址永远都是在下面:

指针铁律1:指针是一种数据类型

#include 
#include 
#include 
//*p 在等号的左边 修改内存//*p 在等号的右边 读取内存char * getstr(){ int *tmp = "hello \n";// 常量区 return tmp;}int main(){ int a; char *p1 = 100;//分配4个字节 p1 = &a; *p1 = 20; //*就像一把钥匙,找到这个地址,并修改它 printf("%d  \n", sizeof(p1)); printf("%d  \n", *p1); int b = 0; b = *p1; printf("%d  \n", b); char p2 = (char *)malloc(100); char p3 = (char *)malloc(100); char *p4 = getstr();// *(p4 + 2) = 'K';  因为返回的是常量 ,不能修改 printf("%s",p4); system("pause");}

指针经典话语:

1,指针指向谁,就把谁的地址赋给指针;

2,指针变量 和 它指向的内存空间变量是两个不同的概念

3,理解指针的关键是内存,没有内存哪里来的指针

变量的本质是一个固定大小的数据块,变量名就是数据块的编号

内存的使用范围:

main函数可以在栈分配内存/堆分配内存/全局分配内存,可以给子函数使用

子函数在栈分配的内存不能给主函数使用,但是堆内存与全局变量是可以给main使用

编译器会为每个程序分配一个内存4区,主函数与子函数公用这个内存4区

建立正确程序运行内存布局图是学好C的关键!

 

指针铁律1:指针是一种数据类型

1)指针也是一种变量,占有内存空间,用来保存内存地址

2)*p 操作内存;

3)*就像一把钥匙,通过一个地址(&a),去修改a变量的标示的内存空间

4)不断的给指针赋值,相当于不停的改变指针的指向。

5) 指针是一种数据类型,是指它指向内存空间的数据类型