任务三----指针与数组

1、数组、数组名、数组首元素三者的地址的关系。

 代码输出结果为:

 由此可知数组名=数组的地址=数组首元素的地址。

1、指针数组

指针数组就是元素均为指针的一个数组,主体是数组,其定义形式为:类型名称   *数组名[数组长度],如:int  *a[10]。

#include<stdio.h>
int main()
{
	int i;
	char *ptr[]={"Pascal","Basic","Fortran","Java","Visual C"};
	for(i=0;i<5;i++)
	{
		printf("%s\n",ptr[i]);
	}
	return 0;
 } 

输出结果为:

指针数组ptr的每个元素ptr[i]都是指针,分别指向一个字符串。ptr[i]中存放字符串的首地址,因此每次输出的都是ptr[i]所代表的字符串。

3、数组指针

数组指针也称一维数组的指针或行指针,主体在于指针,其定义形式为 类型名称  (*指针名)[数组长度] ,如int(*p)[100],注意,不能写成int  *p[100]的形式,因为[]的优先级高于*,[]会首先与p结合成int *(p[100]),使变量类型成为数组,int *为元素类型。

#include<stdio.h>
int main()
{
	int a[5]={1,2,3,4,5};
	int (*p)[5]=&a;
	int i;
	for(i=0;i<5;i++)
	{
		printf("%d\n",*(*p+i));
	}
	return 0;
 } 

输出结果为:

 上面的代码中定义了一个指向含有五个int型数组的指针p,并让指针p指向a数组的首地址。

4、指针的隐式转换

在大多数包含数组的表达式中,数组自动转换成指向数组首元素的指针。也就是说数组名的值是指向数组第1个元素的指针。

#include<stdio.h>
int main()
{
	int a[3]={1,2,3};
	int *p=a;
	printf("%p\n",a);
	printf("%p\n",p);
	printf("%d\n",*p);
	printf("%d\n",a[0]);
}

但是这个规则也有例外 

sizeof返回整个数组所占用的字节而不是一个指针所占用的字节。对数组执行sizeof运算得到整个数组所占大小,对指针执行sizeof运算得到指针本身的大小。

#include<stdio.h>
int main()
{
	int a[3]={1,2,3};
	int *p=a;
	int l_1=sizeof(*p);//int类型指针占4个字节,对指针进行sizeof运算只能得到指针本身的大小
	int l_2=sizeof(a);//而数组a中有三个元素,对数组进行sizeof运算得到4*3=12个字节
	printf("%d\n",l_1);
	printf("%d\n",l_2);
}

 还有一个就是取地址符(&),当对数组取地址时,它返回的是一个指向数组的指针,而非一个指向指针的指针。

#include<stdio.h>
int main()
{
	int a[3]={1,2,3};
	int *p=a;
	printf("%p\n",a);
	printf("%p\n",p);
	printf("%p\n",&a);
	printf("%p\n",&a[0]);
	printf("%p\n",&a[1]);
	printf("%p\n",&a[2]); 
}

 5、指针与内存

malloc函数-----函数原型为 : void *malloc(unsigned  size);

这个函数的功能是向系统申请大小为size的连续内存块,然后把首地址返回,如果申请不成功,则返回NULL。所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL。函数malloc()的返回值类型为void *(这是通用指针的一个重要用途),它可以指向任意类型的变量。

free()函数-----函数原型为void free(void *p);

这个函数的功能是释放由malloc() 函数申请的内存块,p指向此块的首地址,malloc() 函数向系统申请的内存块不会自己主动释放,如果我们不手动释放的话,可能会造成内存泄漏。所以当我们申请的动态内存不再使用时 ,一定要及时释放 。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int n;
	int *p=NULL;
	scanf("%d",&n);
	p=(int *)malloc(n*sizeof(int));//向内存中申请内存
	if(p!=NULL)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d",&p[i]);
		}
		for(int i=0;i<n;i++)
		{
			printf("%d ",p[i]);
		}
	}
	free(p);//释放内存之后,p=NULL;
	return 0;
}

6、指针类型的重要性

不同类型指针所占的字节不同,int型指针占4个字节,char型指针占1个字节,double型指针占8个字节,但是指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。如int *p,指针的类型是int*,但是指针所指向的类型是int。指针的值是指针所指向的内存区或地址,指针也可以进行算术运算,指针加或减一个整数还是指针,指针加或减指针是单位。

#include<stdio.h>
int main()
{
	char a='a';
	char *p1=&a;
	int b=1;
	int c=2;
	int *p2=&b;
	int *p3=&c;
	printf("%p\n",p1);
	printf("%p\n",p1+1);
	printf("%p\n",p2);
	printf("%p\n",p2+1);
	printf("%p\n",p3);
	printf("%p\n",p2-p3);
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值