首页 > 其他分享 >关于我、重生到500年前凭借C语言改变世界科技vlog.12——深入理解指针(2)

关于我、重生到500年前凭借C语言改变世界科技vlog.12——深入理解指针(2)

时间:2024-10-30 12:48:31浏览次数:6  
标签:arr int vlog.12 C语言 地址 数组 sizeof 500 指针

文章目录

1.数组名与地址

有这么一个数组,数组名为 arr

int arr[10] = {1,2,3,4,5,6,7,8,9}
int *p = &arr[0]

在这里 &arr[0] 指的是首元素地址,其实本质上数组名就代表的是数组首元素地址
接下来我们将对以下几个名字进行区分

1.arr
2.sizeof(arr)
3.&arr

1.1 arr

#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;
}

根据以上保留取地址符&和只用数组名,打印对应的地址可以发现
在这里插入图片描述
两个的地址都相同,这就说明了 &arr[0] = arr,即数组名就是首元素地址

1.2 sizeof(arr)

#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;
}

这里关键字 sizeof 计算 arr 的大小,你可能会觉得应该输出首元素的大小?
在这里插入图片描述
不,这里的 arr 不代表首元素大小,而是表示整个数组,计算整个数组的大小,单位是字节

1.3 &arr

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

打印 &arr 和 &arr+1 地址,假设他是跳过一个字节的地址
在这里插入图片描述
很显然,根据代码结果,两段代码地址相差40,那么假设就是错的,所以 &arr 表示的是整个数组的大小

总结:只有 &arr 和 sizeof(arr) 有特殊含义,其他情况下的数组名都代表数组首元素地址

2.指针访问数组

#include <stdio.h>
int main()
{
 int arr[10] = {0};
 //输⼊
 int i = 0;
 int sz = sizeof(arr)/sizeof(arr[0]);
 //输⼊
 int* p = arr;
 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] 也是能够正常打印的
在这里解引用操作符和下标引用符产生的效果相同

本质上p[i] 是等价于 *(p+i),数组元素的访问在编译器处理的时候,也是转换成首元素的地址+偏移
量求出元素的地址,然后解引用来访问的

3.一维数组传参本质

在前面学习的函数篇章中,数组可以传递给自定义函数,那么数组传递的本质是什么呢?

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

通过以上代码调试后可以发现,sz1 = 10,sz2 = 1,同样的算法应该 sz1 = sz2 =10 ,但穿过去的形参根据结果 sizeof(arr) 只计算出一个元素的大小,前面我们提到 arr 表示首元素的地址,那么在数组传参的时候,传递的是数组名,也就是数组传参的时候传递的是首元素的地址

所以函数的形参应该用指针变量来接收一个地址,这也证实了数组传参的本质是传递首元素地址
形参部分既可以写成 int * arr 的指针形式,也可以写成 arr[ ] 的数组形式

4.指针数组

什么是数组指针?什么是指针数组?这里我们重点介绍一下指针数组
指针数组是一个数组,比如整型数组存放的数组,字符数组存放的是字符,那么指针数组存放的就是指针

int* arr[5] = 5个int*

每一个数组里的指针都指向一个地址

5.二级指针

正常的一个常见的指针是一级指针,那么在一个指针里面再嵌套一个指针就是二级指针
是变量就有地址,指针变量也不例外,比如把指针变量的地址需要存放在另一个指针变量里

#include <stdio.h>
int main()
{
  int i = 5;
  int * pi = &i;
  int ** pii = &pi;  
  return 0;
}

*pii 通过对 pii 中的地址进行解引用,这样找到的是 pi , *pii 其实访问的就是 pi
**pii 先通过 *pii 找到 pi ,然后对 pi 进行解引用操作: *pi ,那找到的是 i

博主最近在准备蓝桥杯的校内比赛,更新可能会有所减缓,大家多多谅解!

标签:arr,int,vlog.12,C语言,地址,数组,sizeof,500,指针
From: https://blog.csdn.net/Zero_VPN/article/details/143359346

相关文章

  • “山林不向四季起誓,荣枯随缘”——C语言(爱心+祝福语)代码分享
                    在数字的海洋中,代码是我们共舞的音符。它们跳跃、旋转,编织出一个个美丽的故事。        每一行代码,都像是精心挑选的词汇,构建起我们共同的语言。        在这个由0和1构成的世界,我们用逻辑与情感交织,创造出无数可能。  ......
  • goto语句(C语言)
    一.C语言中的goto语句概念在C语言中,goto是一条无条件跳转语句,它允许程序控制流跳转到同一函数内的某个特定标签处继续执行。使用goto语句时,需要在目标位置定义一个标签,标签由一个标识符后跟一个冒号(:)组成。goto语句的基本形式如下:gotolabel;随后的代码中,如果执行到goto语......
  • C语言顺序表(类似数组结构)
    ////CreatedbyAdministratoron2024/10/25.//顺序表结构//#ifndefORDER_TABLE_H#defineORDER_TABLE_H/*声明顺序表的长度*/#defineSize5/***声明顺序表结构体*/typedefstructTable{int*head;intlength;intsize;}table;/***......
  • C语言链表
    ////CreatedbyAdministratoron2024/10/29.//#ifndefLINK_H#defineLINK_H/***链表的结构体*/typedefstructLink{intelement;structLink*next;}link;#endif//LINK_H////链表//CreatedbyAdministratoron2024/10/28.//#pragmao......
  • C语言链表反转的四种方法
    ////CreatedbyAdministratoron2024/10/29.//#ifndefLINK_H#defineLINK_H/***链表的结构体*/typedefstructLink{intelement;structLink*next;}link;#endif//LINK_H////四种链表反转算法//CreatedbyAdministratoron2024/10/29.......
  • L1-015 c语言跟奥巴马一起画方块
    美国总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!输入格式:输入在一行中给出正方形边长N(3≤N≤2......
  • 2个月搞定计算机二级C语言——真题(6)解析
    1.前言本篇我们讲解2个月搞定计算机二级C语言——真题62.程序填空题2.1题目要求2.2提供的代码#include<stdio.h>unsignedlongfun(unsignedlongn){unsignedlongx=0;intt;while(n){t=n%10;/**********fou......
  • 【C语言】预处理(预编译)详解(下)(C语言最终篇)
    文章目录一、#和##1.#运算符2.##运算符二、预处理指令#undef三、条件编译1.单分支条件编译2.多分支条件编译3.判断符号是否被定义4.判断符号是否没有被定义四、头文件的包含1.库头文件的包含2.本地头文件的包含3.嵌套包含头文件的解决方法使用条件编译指令使用预处理......
  • C语言之长整型有符号数与短整型有符号数转换
            最近考证的新星,问了一个问题:inta=1234565789;为什么在输出%hd时的值为-1379?其实这个很简单,只不过对于可能初入“编程坑”以及经验不是很丰富的朋友来说,感觉知道这么个道理,但就是解释不上来,无法做出实际的推论。作者想说的是,这个知识点亦涉及多方面,比较广泛,......
  • 初学c语言(第一天)
     其实我也不太算是初学,但是也算是初学,这样说有点矛盾哈,让我来解释一下: 首先我是一个今年刚刚毕业的大学生,大学学的专业是电子信息工程,这个专业涉及过c语言,但是我大学期间只顾的潇洒了,没怎么认真学习,只有当大四下学期的时候我们离校需要出去找工作实习时,我才发现我什么都不......