C基础知识复习(下)

结合上一章节的博文   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行给数组指针p
	for (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; //4
	char sex;//1
	int score;//4
	char name[20];//20
	char blood;//1
};
int main()
{
	struct Student s1;
	//sizeof 大小是36   4+1+4+20+1=30  
	// 结构体4字节对齐  sex 在两整型之间  因为需要对齐  所以也被看成4字节   及 4+4+4+20+1=33  最终是36
	printf("sizeof(Student)=%d\n",sizeof(struct Student));
	getchar();
	return 0;
}
优化:
#include <stdio.h>
struct Student
{
	int id; //4
	int score;//4
	char name[20];//20
	char blood;//1
	char sex;//1
};
int main()
{
	struct Student s1;
	//sizeof 大小是32   4+4+20+1+1=30  
	// 结构体4字节对齐   最终是32
	printf("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个字节为0
	for ( 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));


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值