指针与数组

一、指针与一维数组

对指针浅显的认识

int a=0;int *p=&a;
*为解引用 拿到指针指向的内存里面的值
&为取地址 拿到元素所占内存的起始地址

指针玩的就是内存
指针就像拿钥匙套娃开门

*就像万能钥匙,p就像门牌号
*打开对应门牌号的门,进入里面
&拿到对应门牌号外面的门牌号,回到外面

有的门开了就能拿到东西,这就是一级指针
有的门开了里面还是一扇门,只能拿到门牌号,这就是多级指针
有的门开了,里面不只是一扇门,是一层楼,单用钥匙只能拿这层楼的起始门牌号,这就是数组指针
在这里插入图片描述

注意

一定要理解指针的类型、指针指向的类型
这对于 解引用和指针算术 很重要
指针加1是根据指针的类型来加

如:
int a[2] a的类型为int * 指向的类型为 int
int a[3][2] a的类型为int *[2] 指向的类型为 int *

1.1、int a[] = {1,2}; int *p = a

数组类似于指向位置固定的指针
即a除了不能 进行a++,其他用法和指针差不多

a的类型为int[2],p的类型为int *
a=数组的首地址
a = &a[0] = &a 只是地址相等 意义不一样
&a是一个数组指针 其类型为 int (*)[2];
a+1 相当于 a的地址+sizeof(int)*1
&a+1 相当于 a的地址 + sizeof(int [2])*1

	int a[]={3,2,1};
	int *p = a;
	printf("p = %d\n",p);
	printf("&a = %d\n",&a);
	printf("a = %d\n",a);
	printf("&a[0] = %d\n",&a[0]);
	printf("&p = %d\n\n",&p);
	
	printf("*p = %d\n",*p);
	printf("a[0] = %d\n",a[0]);

在这里插入图片描述

1.2、 *(p+i) = p[i] = a[i] = *(a+i)

p+i = &p[i] = a+i = &a[i]

假设 p=200 则 p+n =200+n*size
size = p所指向的类型的大小

	int a[]={1,2,3};
	int *p = a;
	printf("*(p+1) = %d\t",*(p+1));
	printf("p[1] = %d\n",p[1]);
	printf("*(a+1) = %d\t",*(a+1));
	printf("a[1] = %d\n\n",a[1]);
	
	printf("p = %d\n",p);
	printf("p+1 = %d\n",p+1);
	printf("&p[1] = %d\n",&p[1]);
	
	printf("a+1 = %d\n",a+1);
	printf("&a[1] = %d\n",&a[1]);
	

在这里插入图片描述

1.3、一维数组作为参数传入函数

数组作为参数传入函数时,函数只会生成一个指针来保存传入数组的首地址
即 fun(int a[ ]) = fun(int* a)
数组作为参数传入函数被修改后,main中也会被修改,
而一般变量传入则不会

void fun(int a[]){
	a[0] = 6;
	printf("f:sizeof(a) = %ld\n",sizeof(a));
	printf("f:sizeof(int*) = %ld\n",sizeof(int*));
	
}
int main(){
	int a[]={1,2,3,4,5};
	int *p=a;
	printf("m:sizeof(a) = %ld\n",sizeof(a));//5*4
	fun(a);
	printf("m:a[0] = %d\n",a[0]);//5*4
}

在这里插入图片描述

1.4、字符串

字符串必须以\0结束,计算字符串长度计算到 \0 为止

  • sizeof
    用于计算变量本身所占用的字节数,而不是变量指向的地址所占用的空间大小
  • strlen
    用于计算以 NULL (\0)结尾的字符串中字符的个数
    /*
	char name[] = “John”  --->  name[4]=’\0’  --->  sizeof(name)=5
    char name[20] = “John”    ---->  strlen(name) = 4   sizeof(name)=20
    char a[] = “abc” 隐含\0
    char b[] = {"abc"} 隐含\0
    char c[] = {‘a’,’b’,’c’ }不隐含\0
   */
 
    char a[]="hi";
	char b[]={'h','i'};
	char c[]={"hi"};
	printf("strlen(a) = %d\n",strlen(a));
	printf("strlen(b) = %d\n",strlen(b)); //可能统计垃圾数据
	printf("strlen(c) = %d\n",strlen(c));
	printf("sizeof(a) = %d\n",sizeof(a));
	printf("sizeof(b) = %d\n",sizeof(b));
	printf("sizeof(c) = %d\n",sizeof(c));

在这里插入图片描述

1.5、两种定义方式

char w[] = “hi” 被定义在栈区可以被修改
char *w = “hi” 被定义在常量区不能修改

二、指针与多维数组(整体思维)

2.1、int a[ ][3]={1,2,3,4,5,6}

int a[2][3]; int (* p)[3] = a;
不能写成int **p= a, 指针类型不同

a的类型int (* )[3]; a指向类型int [3] ;
*a的类型 int*; *a指向类型int;*a = a[0];
可将二维数组看做一维,只是里面元素还是一维数组

在这里插入图片描述

	int a[][3]={1,2,3,4,5,6};
	printf("sizeof(int* [3]) = %d\n",sizeof(int* [3]));
	printf("sizeof(int [3]) = %d\n",sizeof(int [3]));
	printf("sizeof(int) = %d\n",sizeof(int));
	
	printf("a = %d\t",a);
	printf("a+1 = %d\n",a+1);
	
	printf("*a = %d\t",*a);
	printf("*a+1 = %d\n",*a+1);

在这里插入图片描述

2.2、a[i][j] = *(a[i]+j) = *( *(a+i)+j)

        /* 
        a是二维数组的名字,也是二维数组的首地址,将一维数组看做一个整体,那可将a看做一维数组 
        a的类型为int (*)[3]  a中元素为 a[0] a[1]
       
        a[0]是一维数组的名字,也是一维数组的首地址 a[0]的类型为int *
        a[0]中元素为 a[0][0] a[0][1] a[0][2]
        
        a = *a = a[0]= &a[0][0]
        a+i = &a[i]; *(a+i) = a[i]
        a[i][j] = *(a[i]+j) = *(*(a+i)+j) 
        */
        
		int a[2][3]={1,2,3,4,5,6};
		printf("一维数组:\n");
		printf("a = %d\n",a);
		printf("*a = %d\n",*a);
		printf("&a = %d\n",&a);
		printf("a[0] = %d\n",a[0]);
		printf("&a[0][0] = %d\n\n",&a[0][0]);
		
		printf("二维数组:\n");
		printf("a[1][2] = %d\n",a[1][2]);
		printf("*((a[1])+2) = %d\n",*((a[1])+2));
		printf("*(*(a+1)+2) = %d\n",*(*(a+1)+2));

在这里插入图片描述

2.3、int c[3][2][2]

int (* p)[2][2] = c;

假设 p=200 则 p+n =200+n* size
size = p所指向的类型的大小

p的类型 int(*) [2][2],指向类型 int [2][2]
*p的类型 int(*) [2],指向类型 int [2]
**p的类型 int(*); 指向类型int

在这里插入图片描述

	int a[3][2][2]={0};
	int (*p)[2][2] = a;
	printf("sizeof(int [2][2]) = %d\n",sizeof(int [2][2]));
	printf("sizeof(int [2]) = %d\n",sizeof(int [2]));
	printf("sizeof(int) = %d\n",sizeof(int));
	
	printf("p = %d\t",p);
	printf("p+1 = %d\n",p+1);
	
	printf("*p = %d\t",*p);
	printf("*p+1 = %d\n",*p+1);
	
	printf("**p = %d\t",**p);
	printf("**p+1 = %d\n",**p+1);

在这里插入图片描述

2.4、c[i][j][k] = *( *( *(c+i)+j)+k)

c[i][j][k] = *((c[i][j]+k) = *(*(c[i]+j)+k)

	//int a[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
	int c[3][2][2]={{{1,2},{3,4}},
				   {{5,6},{7,8}},
				   {{9,10},{11,12}}};
	 
	printf("c[2][0][1] = %d\n",c[2][0][1]);
	printf("*(*(*(c+2)+0)+1) = %d\n",*(*(*(c+2)+0)+1));
	printf("*((c[2][0]+1) = %d\n",*((c[2][0]+1)));
	printf("*(*(c[2]+0)+1) = %d\n\n",*(*(c[2]+0)+1));
	

在这里插入图片描述

2.5、多维数组作为参数传入函数

int c[3][2][2] ;
void fun(int (* c)[2][2]])
void fun(int ***c)

int a[2][3];
void fun(int (* a)[3]])
void fun(int **a)

void fun1(int ***p){
	printf("p = %d\n",p);
	printf("wrong:p+1 = %d\n\n",p+1);
}

void fun2(int (* p)[2][2]){
	printf("p = %d\n",p);
	printf("right:p+1 = %d\n",p+1);
}

int main(){
	//int a[3][2][2]={1,2,3,4,5,6,7,8,9,10,11,12};
	int c[3][2][2]={{{1,2},{3,4}},
				   {{5,6},{7,8}},
				   {{9,10},{11,12}}};
	printf("c = %d\n",c);
	printf("c+1 = %d\n\n",c+1);
	fun1(c);
	fun2(c);
}

在这里插入图片描述

能力有限,仅供参考
笔记是自己理解和总结的,根据一个印度老师的视频
原视频讲的通俗易懂,非常详细
封面是模拟程序在内存运行时的情况
封面和视频来源:https://www.bilibili.com/video/BV1bo4y1Z7xf?spm_id_from=333.999.0.0

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值