数组和指针

数组和指针

数组

数组:一系列相同类型元素的集合

数组声明
//一些数组声明
#include<stdio.h>
int main()
{
	int a[10];  //包含从a[0]到a[9]10个int类型的元素,不包含a[10]
	float f[20]; //20个float类型的元素
	double d[20]; //20个double类型的元素
	
	return 0;
}

数组的初始化
int a[10]={0,1,2,3,4,5,6,7,8,9};//每个元素之间以逗号隔开0赋给a数组的首个元素a[0],1赋给a[1]以此类推把9赋给a[9];


int a[]={0,1,2,3,4,5,6,7,8,9};
在定义初始化中也可不在方括号中加入数字,直接在后面赋值 计算机根据后面元素个数自动匹配数组大小。


部分初始化
int a[10]={0,1,2,3,4,5};
这句只初始化了a[0]到a[5]六个元素,后面剩余的元素全部会被初始化成为0
在C里也可指定要初始化的元素
int a[10]={[5]=11};
这样就把a[5]初始化成了11
多维数组
二维数组
int year[2][12]={ {1,2,3,4,5,6,7,8,9,10,11,12} , {1,2,3,4,5,6,7,8,9,10,11,12} };
一年有12个月,两年有24个月
主数组有两个数组元素,每个数组元素又内含12个元素


一维数组相当于写了一行字
二维数组相当于写了几行字
三维数组就相当于写了好几张字,a[2][5][10]这个相当于写了两张,然后每一张写了5行,每一行又写了10个字。
以此类推还有四维数组,五维…

数组和指针

数组名是数组首个元素的地址
如果a是一个数组,那么 a==&a[0]

数组作为函数形参

image
数组作为函数形参传入到函数中相当于传入了一个地址

函数参数表中的数组 a[] 实际上是一个指针,将a[]替换为*a后程序仍然可以正常运行
image
在函数参数表中 int a[]实际上是声明了a是一个int类型的指针,并且a还是一个int型的数组元素。

image
数组名是数组首个元素的地址
我们给函数传入一个 x 就相当于传入了一个数组首个元素x[0]的地址

还可以改一下程序,让我们给函数直接传入一个地址
image
程序依旧正常运行,这样是不是就证明了int a[]这个形参就是让我们给函数传入一个地址(指针,a[]==*a)。

//test
#include<stdio.h>
void test(int a[]);
int main()
{
	int x[10] = { 0,1,2,3,4,5,6,7,8,9 };
	printf("sizeof(x)=%d\n", sizeof(x));
	printf("&x=%p\n", &x);
	printf("x=%p", x);
	test(&x[0]);
	printf("x[0]=%d\n", x[0]);

	return 0;
}
void test(int a[])
{
	printf("sizeof(a)=%d\n", sizeof(a));
	a[0] = 112;
	printf("%p\n", &a[0]);
}

下面的四种函数原型都是等价的

int test(int *a);
int test(int a[]);

因为函数原型可以省略参数名,所以我们还可以写成这样
int test(int *);
int test(int []);
但是在函数定义中必须要加上参数名,不可省略,不然的话传入的值让谁保存嘞!
所以函数定义我们就得使用下面这两个:
int test(int *a);
int test(int a[]);

指针

指针是一个地址

int a;
int *p; //指针的声明
p=&a;  //初始化  运算符 & 是用来取地址的


*p=12   指针的间接引用 *p==a    *p=12 => a=12
        指针的间接引用又称解引用,* 运算符给出指针所指向地址上所存储的值
		 

####野指针
没有有效的地址空间的指针,也就是未初始化的指针

int *p;//未初始化的指针
*p=10//错误    p是一个随机值,我们不知道p将会指向哪里,可能不会出错,但也可能指向一个特殊的地方使得程序崩溃。

####空指针
为了避免使用未初始化的指针,我们定义了一个 NULL (NULL==0)使得指针在声明时就指向一个无效的访问区域。
int *p=NULL;
p 所指向的存储空间一定是一个无效的访问区域。

####指针作为函数形参

#include<stdio.h>
int sum(int *x,int y);
int main()
{
	int a=10;
	int b=2;
	sum(*a,b);
	printf("%d",a);
	return 0;
}
int sum(int *x,int y)
{
	return *x=*x+y;
}

image
就是给函数传入了一个地址。

####指针的运算
**指针加上一个整数n **
指针加上一个整数n相当于指针加上了一个 n*sizeof(类型名)
递增指针 p++ 、++p 加上了一个 sizeof(类型名)

指针减去一个整数n
指针减去一个整数n相当于指针减去了一个 n*sizeof(类型名)
递减指针 p-- 、–p 减去了一个 sizeof(类型名)

指针相减
在同一个数组里,两个指针指向不同的元素,指针作差可以用来计算两个元素之间的距离。

指针和const

指针是const
指针指向的地址不可修改,只能是第一次得到的地址,但是指针所指向的变量可以修改。

所指向的变量是const
指针指向的地址可以修改,但是不能通过指针去修改变量的值,指针指向的变量并不会成为const(除非变量本身就是const),只是无法通过指针去修改变量,const的作用对象一直是指针。

数组和指针

数组变量是特殊的指针
数组变量本身表达地址
a==&a[0]
[]运算符可以对数组做,也可以对指针做。
例如:
image
*运算符可以对指针做,也可以对数组做。
例如:
image

#####指针和二维数组

//二维数组相当于是一个数组的数组
int a[4][2] = { { 7, 11}, { 12, 31},{ 4, 3},{ 2, 1} };
int (*p)[2]=a;  //数组指针(表示二维数组)
p		二维数组的首个数组元素的地址			=> &a[0]
p+2		二维数组的第3个数组元素的地址			=> &a[2]
*(p+2)		二维数组的第3个数组元素的首个元素的地址	=> &a[2][0]=4
*(p+2)+1	二维数组的第3个数组元素的第二个元素的地址	=> &a[1]
*(*(p+2)+1)	二维数组的第3个数组元素的第二个元素的值	=> a[2][1]=3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值