C语言学习系列-->看淡指针(2)

简介: C语言学习系列-->看淡指针(2)

前言

不把指针学的扎实,可不敢说自己C语言基础学的好

一、数组名的理解

#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);
  return 0;
}

输出结果

所以,数组名就是数组第一个元素的地址

数组名就是数组⾸元素(第⼀个元素)的地址是对的,但是有两个例外:

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

单位是字节

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

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

#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[0]+1 = %p\n", &arr[0] + 1);
  printf("arr = %p\n", arr);
  printf("arr+1 = %p\n", arr + 1);
  printf("&arr = %p\n", &arr);
  printf("&arr+1 = %p\n", &arr + 1);
  return 0;
}

输出结果

&arr[0] = 0077F820
&arr[0]+1 = 0077F824
arr = 0077F820
arr+1 = 0077F824
&arr = 0077F820
&arr+1 = 0077F848

这⾥我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,是因为&arr[0] 和 arr 都是

⾸元素的地址,+1就是跳过⼀个元素。

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

二、使用指针访问数组

#include<stdio.h>
int main() {
  int arr[10] = { 0 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  int* p = arr;
  int i = 0;
  for (i = 0; i < sz; i++) {
    scanf("%d", p + i);
    //也可以写成scanf("%d",arr+i);
  }
  for (i = 0; i < sz; i++) {
    printf("%d ", *(p + i));
  }
  return 0;
}

本质上p[i] 是等价于 *(p+i),arr[i] 应该等价于 *(arr+i)

三、一维数组传参本质

之前我们都是在函数外部求数组的个数,那如果在函数内部呢?

数组名是数组⾸元素的地址;那么在数组传参的时候,传递的是数组名,也就是说本质上数组传参传递的是数组⾸元素的地址。

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

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

数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。

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

⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

四、二级指针

是变量都有地址

那么,指针变量也是变量,它的地址在哪呢?

存放在二级指针

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

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

**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* parr[3] = { arr1,arr2,arr3 };
  int i = 0;
  int j = 0;
  for (i = 0; i < 3; i++) {
    for (j = 0; j < 5; j++) {
      printf("%d ", parr[i][j]);
      //printf("%d", *(*(parr + i) + j));
      //parr[i][j] == *(*(parr + i) + j);
    }
    printf("\n");
  }
  return 0;
}

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

上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。


目录
相关文章
|
2天前
|
C语言
c语言指针总结
c语言指针总结
15 1
|
23小时前
|
存储 安全 编译器
C语言详解指针(指针海洋的探索,将传值与传址刻在心里)
C语言详解指针(指针海洋的探索,将传值与传址刻在心里)
4 0
|
2天前
|
C语言
C语言(指针详解)重点笔记:指针易错点,都是精华
C语言(指针详解)重点笔记:指针易错点,都是精华
6 0
|
2天前
|
存储 C语言 索引
指针学习(特殊指针)
指针学习(特殊指针)
8 0
|
2天前
|
存储 C语言
C语言指针讲解(适用于初学者)
C语言指针讲解(适用于初学者)
6 0
|
2天前
|
人工智能 测试技术 C语言
C语言学习
C语言学习
14 1
|
2天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
2天前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
2天前
|
存储 程序员 编译器
爱上C语言:指针很难?来来来,看看这篇(基础篇)
爱上C语言:指针很难?来来来,看看这篇(基础篇)
|
2天前
|
存储 C语言
指针深入解析(C语言基础)带你走进指针,了解指针
指针深入解析(C语言基础)带你走进指针,了解指针

热门文章

最新文章