指针知识点笔记2

数组名的理解
数组名本来就是地址,⽽且是数组⾸元素的地址,即:

&arr[0]=arr

上面代码,打印出来的地址都是一样的,证明了:数组名就是数组⾸元素(第⼀个元素)的地址

但是有两个例外:

• sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节

#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));
return 0;
}
//输出的结果为40

• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)

除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。

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

上面代码输出的结果一样,为什么呢?&arr与arr又有什么区别呢?

因为这三个的地址都开始在同一地方,也就是都是从数字1那个地方开始读地址

&arr与arr又有什么区别呢?

&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,所以+1的时候,它们就会跳过一个元素(4字节)

而&arr 和 &arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的

使⽤指针访问数组
 

*(p+i)=*(arr+i)===arr[i]

加法是可以交换律的
*(i+arr)=i[arr]
因此可以得出[]只是操作符

1.数组就是数组,是可以存放一个或者多个数组的
2.指针变量是一个变量,是可以存放地址的变量
数组和指针不是一回事
但是可以是一种指针来访问数组

为什么可以使用指针来访问数组呢
1.数组在内存中是连续存放的
2.指针的元素可以很方便来遍历数组,取出数组的内容

⼀维数组传参的本质

因为int* arr=int arr[],这实际上是指针变量,不是数组

数组传参的时候,形参可以写成数组,也可以写成指针
写成数组的形式,最简单,是为了方便理解,容易接受这种语法
但是即使写成数组的形式,本质上还是指针

eg:

#include<stdio.h>
void test(int arr[10]  /*也可以写成int* arr*/,int sz)
{
 printf("%d",sz);
}
int main()
{
  int arr[5]={1,2,3,4,5};
  int sz=sizeof(arr)/sizeof(arr[0]);
  test(arr,sz)
  return 0;
}

arr是数组名,数组名表示数组首元素的地址

数组传参的本质,传递的是数组首位元素的地址
所以,形参即使写成数组的形式,本质上也是一个指针

函数内部是没办法求的数组元素个数的原因:

函数形参的部分理论上应该使⽤指针变量来接收⾸元素的地址。那么在函数内部我们写

sizeof(arr) 计算的是⼀个地址的⼤⼩(单位字节)⽽不是数组的⼤⼩(单位字节)

⼆级指针:指针变量也是变量,是变量就有地址,那指针变量的地址存放的地方

#include<stdio.h>
int main()
{
  int a=20;
  int* pa=&a;
  int* *ppa=&pa;


  return 0;
}

二级指针变量是用来存放一级指针变量的地址

int* *解读:

分开理解,将分成int*和*两个部分

int*表示ppa指向的pa类型是int*

第二个*表示说明ppa是指针变量

注意:二维指针和二维数组没有必然的联系

对于⼆级指针的运算有:

1.*ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa

int b = 20;
*ppa = &b;//等价于 pa = &b

2.**ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

指针数组
类比一下:

整形数组:是存放整型的数组,

字符数组:是存放字符的数组。

所以指数数组是存放指针的数组。

指针数组模拟⼆维数组
 

#include<stdio.h>
int main()
{
  int arr1[5]={1,2,3,4,5};
  int arr2[5]={2,3,4,5,6};
  int arr3[5]={3,4,5,6,7};
  int* pa[5]={arr1,arr2,arr3};
  int i=0;
  int j=0;
  for(i=0;i<5;i++)
  { 
    for(j=0;j<5;j++)
    {
      printf("%d",pa[i][j]); //也可以写成*(*(pa+i)+j)
    }
  }
  return 0;
}

parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。

实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值