深度理解指针和数组,超详细,满满干货(一)

本文深入探讨了C语言中的指针和数组,包括指针的概念、指针变量、内存布局、解引用以及如何存储到指定内存地址。同时,分析了数组的内存布局,理解&a与&a[0]的区别,以及数组名作为左值和右值的特性。内容旨在帮助读者更好地理解和运用指针与数组,提高编程效率。
摘要由CSDN通过智能技术生成

目录

**指针的深度理解

*什么是指针

*有没有指针变量这个概念

*指针和指针变量有什么区别

*为什么要有指针

*指针的内存布局

*指针的解引用 

*如何将数值存储到指定的内存地址

**数组的深度理解

*数组的内存布局

*理解&a和&a[0]的区别

*数组名a作为左值和右值的区别

(一)指针的深度理解

[一]指针

(1)什么是指针?

指针就是地址,那么地址是什么呢??地址就是数据,而数据可以被保存在变量空间中。

(2)有没有指针变量这个概念?

答案是有,保存指针(地址)的变量就叫做指针变量

(3)指针和指针变量有什么区别?

int main()

{

int a = 10;

int *p = &a;//p的空间指向a,而p的内容为a的地址

p = 10; //此时p为左值,表示的是p的空间,即p的空间指向10

 int *q = p; //此时p为右值,表示的是p的内容

*p = 10; //解引用p所利用的是p的右值,即*p就是a

system("pause");

return 0;

}

结论:指针就是地址,指针变量就是变量,变量内部保存的是指针(地址) 

(4)为什么要有指针?

例:好比一栋宿舍楼没有门牌号,小明随机进入其中一个房间,打电话叫张三找他,张三并不知道他在哪个房间,只能每层楼一个一个房间的找过去,非常浪费时间。而指针就相当于门牌号,有利于寻找,提高编码时的效率

[二]指针的内存布局

[三]指针的解引用 

int main()

{

        int a=20;

        int *p=&a;

        *p=30;

        return 0;

{

*p的完整理解是,取出p中的地址,访问该地址指向的内存单元(空间或内容)(本质上是一种通过指针变量访问的间接寻址方式)

口诀:对指针解引用,就是指针指向的目标,所以*p就是a

[四]如何将数值存储到指定的内存地址

在比较老的编译器中可以通过,这种寻址方式已经不适用,但是有必要知道这种思维方式

int main()

{

int a = 10;//假设a变量的地址是0x12345678,那么访问a变量,还可以直接通过指针方式进行访问

printf("%d\n", *(int*)0x12345678); //本质是一种直接寻址的方式

*(int*)0x12345678 = 100; //本质是一种直接寻址的方式

 system("pause");

return 0;

}

 (二)数组的深度理解

数组:数组是具有相同数据类型的集合

int main

{

#define N 10

        int a[N]={0};

        int b[]={0};

        int c[10]={0};//数组的下标可以是宏定义的常数,整数,或者空

        int n=10;

        int d[n]={0};//在C89、C90中这种定义方法是无法通过编译的,而在C99中可以

        return 0;
}

[一]数组的内存布局

 我们发现,先定义的变量,地址是比较大的,后续依次减小

a,b,c都在main函数中定义,也就是在栈上开辟的临时变量。而a先定义意味着,a先开辟空间,那么a就先入栈,所以a 的地址最高,其他类似。

 

 而为什么a[0]的地址最小,a[9]的地址最大呢?数组有这么多元素,那么肯定是a[0]先开辟空间,a[0]的地址肯定是最大的。但是为什么a[0]的地址最小?这与我们上面所说的是否相违背??

 结论:对于C语言中的变量,会先开辟出一块变量所需的内存空间,然后在进行变量中各个子变量的分配

[二]理解&a和&a[0]的区别

 &arr[0] 和 &arr虽然地址数字一样大,但是类型意义完全不同。

 口诀:对指针+1,本质上是加上其所指向类型的大小(如果发生类型转换后+1则加上转换后转换后的类型的大小),对于二级即以上的指针+1,则为加上4个字节(地址大小)(32位)(64位加上8个字节)

 [三]数组名a作为左值和右值的区别

//数组名可以做右值,代表数组首元素的地址
//数组名做右值,本质等价于&arr[0]

#include<stdio.h>
#include <windows.h>
#define N 10
int main()
{
int arr[N] = { 0 };
char *p = arr;
system("pause");
return 0;
}

 

数组名不可以做左值!
能够充当左值的,必须是有空间且可被修改的,arr不可以整体使用,只能按照元素为单位进行使用

#include<stdio.h>
#include <windows.h>
#define N 10
int main()
{
int arr[N] = { 0 };
arr = { 1, 2, 3, 4, 5 };//编译器报错
system("pause");
return 0;

总结: 这是第一部分的内容。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值