C 提高第一天复习

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




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

选择法或者冒泡法排序

在一个函数内排序

通过函数调用的方式排序

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

#include<stdio.h>#include<stdlib.h>#include<string.h>intmain(){inti=0;intj=0;inttmp=0;inta[]={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");}编译运行:36654321122992334323112232325466992334请按任意键继续...


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

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



数据类型概念:

“类型”是对数据的抽象

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

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




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

#include<stdio.h>#include<stdlib.h>#include<string.h>structteacher1{charname[64];intage;}Teacher1;//使用typedef,以后定义就是这样了Teacher2t2;typedefstructteacher2{charname[64];intage;}Teacher2;intmain(){intb[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代表跨过整个数组地址structteacher1t1;Teacher1.age=0;Teacher2t2;typedefintu32;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<stdio.h>#include<stdlib.h>intmain(){inta=10;intb[10];printf("inta:%d\n",sizeof(a));printf("inta:%d\n",sizeof(int*));printf("intb:%d\n",sizeof(b));printf("intb:%d\n",sizeof(b[0]));printf("intb:%d\n",sizeof(*b));printf("hello.....\n");return0;}编译运行:C:\Users\chunli>gccmain.c&ainta:4inta:4intb:40intb:4intb:4hello.....



常量的探讨:

#include<stdio.h>#include<stdlib.h>#include<string.h>char*getstr1(){char*p="1234";returnp;}char*getstr2(){char*p="5678";returnp;}intmain(){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<stdio.h>#include<stdlib.h>#include<string.h>char*getstr1(){char*p="1234";returnp;}char*getstr2(){char*p="1234";returnp;}intmain(){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<stdio.h>#include<stdlib.h>#include<string.h>//堆char*getmem(intsize){char*p=NULL;p=(char*)malloc(size);returnp;}//栈//return不是把内存块返回出来,而是把首地址返回了char*getmem2(){charp[20];strcpy(p,"haha2\n");returnp;//【危险!】p即将释放,但是地址返回去来了。}intmain(){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<stdio.h>#include<stdlib.h>#include<string.h>intmain(){inta;intb;printf("&a=%d\n",&a);printf("&b=%d\n",&b);system("pause");}编译运行:C:\Users\chunli>gcc-omain.exemain.c&main&a=2686652&b=2686648请按任意键继续...

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



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

#include<stdio.h>#include<stdlib.h>#include<string.h>//*p在等号的左边修改内存//*p在等号的右边读取内存char*getstr(){int*tmp="hello\n";//常量区returntmp;}intmain(){inta;char*p1=100;//分配4个字节p1=&a;*p1=20;//*就像一把钥匙,找到这个地址,并修改它printf("%d\n",sizeof(p1));printf("%d\n",*p1);intb=0;b=*p1;printf("%d\n",b);charp2=(char*)malloc(100);charp3=(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) 指针是一种数据类型,是指它指向内存空间的数据类型