C基础知识复习(下)

来源:互联网 发布:真诚网络卖qq号可信吗 编辑:程序博客网 时间:2024/06/05 10:49

结合上一章节的博文   http://blog.csdn.net/hucblog/article/details/44940617


我们在进行下部分的复习



1.指针高级

    1.1指针定义

1.1.1 指针数组

首先我们定义一个整型数组 
int array[6];
整型数组,数组中的每个元素都是一个整型元素

那么,推算出指针数组的定义
int* array[6];
指针数组,数组中的每个元素都是一个指针

#include <stdio.h>#include <stdlib.h>int main(){char *p[]={"hello","world","nice","fuck"};int i;for (i = 0; i < 4; i++){printf("%p\t%s\n",p[i],p[i]);}system("pause");return 0;}
如上代码:
上图是在ubuntu测试的,在windows平台下,Ro.Data区的地址并不是连续的,这很纠结

在Ubuntu中64位编译,指针在栈中占有8个字节,在32位中占4字节,所以这里使用sizeof(p)   得到的结果有16或32两种可能

1.1.2二重指针

二重指针是指向指针的指针

1.1.3 数组指针

数组指针是一个指针,指向的是一个数组

我们定义一个int行的指针是这么定义的     
int *p;
那么定义一个指向int行数组的指针,
int (*p)[10]
#include <stdio.h>#include <stdlib.h>int main(){int i;char arr[3][10]={"nice","hello","sorry"};//定义一个二维数组char (*p)[10];//定义一个数组指针,相当于二维数组的行指针p=&arr[0];//将二维数组的第0行给数组指针pfor (i = 0; i < 3; i++){printf("%s\n",*(p+i));}system("pause");return 0;}

上续代码是数组指针和二维数组结合的使用方式

1.1.4   函数指针

这个指针指向的是一个函数,定义如下
int (*p)(int,int);
应用:
#include <stdio.h>#include <stdlib.h>int add(int a,int b){return a+b;}int sub(int a,int b){return a-b;}int mul(int a,int b){return a*b;}int division(int a,int b){return a/b;}int computing(int (*p)(int,int),int a,int b){return p(a,b);}int main(){printf("a=9\tb=3\nadd=%d\tsub=%d\tmul=%d\tdivision=%d\n",computing(add,9,3),computing(sub,9,3),computing(mul,9,3),computing(division,9,3));system("pause");return 0;}

1.2 指针加1

1.2.1  指针数组加1

#include <stdio.h>#include <stdlib.h>int main(){char *p[3]={"nice","mono","sheit"};int i;//p是一个数组,数组里有三个字符串指针//sizeof(p)   其实就是数组的大小   在32位中指针占4字节   所有此时是4*3=12  64位系统则是8*3=24//sizeof(*p)  *p可以看我p[0]   取出来的是一个指针  所以在32位系统中是4  64位系统中是8//那么p+1   就是加过一个指针 4个字节  printf("sizeof(p)=%d\tsizeof(*p)=%d\n",sizeof(p),sizeof(*p));for (i = 0; i < 3; i++){printf("%s\n",*(p+i));}//总结:p是数组,数组每个元素又是指针,所以指针数组和二重指针对等system("pause");return 0;}

1.2.2 二重指针加1

#include <stdio.h>#include <stdlib.h>int main(){char **p;//p是一个指向指针的指针,其实还是个指针//sizeof(p)  p是指针,所以为4//sizeof(*p)  取值*p还是指针   所以为4//那么p+1就加过4个字节printf("sizeof(p)=%d\tsizeof(*p)=%d\n",sizeof(p),sizeof(*p));system("pause");return 0;}

1.2.3函数指针加1

函数指针加1是没有意义的,函数指针也是指针   所以sizeof(p)是4

    1.2.4 数组指针

#include <stdio.h>#include <stdlib.h>int main(){char (*p)[10];//p是一个指针//sizeof(p)  p是指针,所以为4//sizeof(*p)  取值*p是数组,数组有10个char元素   所以为10//那么p+1就加过一个数组,10个字节printf("sizeof(p)=%d\tsizeof(*p)=%d\n",sizeof(p),sizeof(*p));system("pause");return 0;}

             最后,指针数组就是二重指针,数组指针就是二维数组

2.typedef

typedef  给类型取一个别名,作用:1.封装了数据类型,方便移植    2.简化函数指针的定义

2.1 typedef和define的区别

#include <stdio.h>typedef char* newtype1;#define newtype char*int main(){newtype1 p1,p2;p1="hello";p2="world";return 0;}
使用typedef时   p1和p2  都是指针。   使用define则p1是指针   p2是char      因为define定义的   在编译期间自行展开    最终编译就是   char *p1,p2;     typedef  则是char *p1,char *p2;


3.结构体

3.1 结构体的优化

未优化:
#include <stdio.h>struct Student{int id; //4char sex;//1int score;//4char name[20];//20char blood;//1};int main(){struct Student s1;//sizeof 大小是36   4+1+4+20+1=30  // 结构体4字节对齐  sex 在两整型之间  因为需要对齐  所以也被看成4字节   及 4+4+4+20+1=33  最终是36printf("sizeof(Student)=%d\n",sizeof(struct Student));getchar();return 0;}
优化:
#include <stdio.h>struct Student{int id; //4int score;//4char name[20];//20char blood;//1char sex;//1};int main(){struct Student s1;//sizeof 大小是32   4+4+20+1+1=30  // 结构体4字节对齐   最终是32printf("sizeof(Student)=%d\n",sizeof(struct Student));getchar();return 0;}

可以看出节省了4个字节。    

总结,结构体中的成员尽量相同类型的放在一块

4.动态内存分配

4.1 malloc和free

#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){int *p=(int *)malloc(100);//向堆中申请100个字节int i;memset(p,0,100);//初始化这100个字节为0for ( i = 0; i < 25; i++){printf("%d\n",p[i]);}//p++;//如果p不是首地址,释放时会出错free(p);//释放堆内存,p的地址不能改变 否则释放出错getchar();return 0;}
可以使用malloc解决,数组不能动态分配大小的问题
scanf("%d",&i);int *p=(int *)calloc(i,sizeof(int));


0 0