第28课 指针和数组分析(上)

码海织云使
• 阅读 873

数组的本质:
·数组是一段连续的内存空间
·数组的空间大小为为sizeof(array_type)*array_size
·数组名可看做指向数组第一个元素的常量指针
例子28-1:

include "stdio.h"

int main()
{

int a[5] = {0};
int* ,p = NULL;
printf("a = 0x%x\n",(unsigned int)(a));
printf("a + 1 = 0x%x\n",(unsigned int)(a + 1));

printf("p = 0x%x\n",(unsigned int)(p));
printf("p + 1 = 0x%x\n",(unsigned int)(p + 1));

}
输出结果:
a = 0xfbfc20
a + 1 = 0xfbfc24
p = 0x0
p + 1 = 0x4

指针运算的结果还是一个值,是一个地址值

指针的运算
·指针是一种特殊的变量,与整数的运算规则为
p+n;⬅➡(unsigned int)p + nsizeof(p);
指针P+n就等于指针p所保存的地址值+n*所指向类型的大小
int *p = null;
p + 1 ==> 0 + 1 sizeof(p) ==> 0 + 1 * sizeof(int) ==> 4

a = 0xfbfc20
a + 1 = 0xfbfc20 + 1 sizeof(a) = 0xfbfc20 + 1 sizeof(a[0]) = 0xfbfc20 + 1 sizeof(int) = 0xfbfc24

结论:当指针p指向一个同类型的数组的元素时:P+1将指向当前元素的下一个元素;p-1将指向当前元素的上一个元素

·指针之间只支持减法运算
·参与减法运算的指针类型必须相同

p1-p2;⬅➡((unsigned int)p1 - (unsigned int)p2)/sizeof(type);
注意:
1.只有当两个指针指向同一个数组的元素时,指针相减才有意义,其意义为指针所指元素的下标差
2.当两个指针指向的元素不在同一个数组中,结果为定义

指针的比较
·指针也可以进行关系运算(<,<=,>,>=)
·指针关系运算的前提是同时指向同一个数组中的元素
·任意两个指针之间的比较运算(==,!=)无限制
·参与比较运算的指针类型必须相同

例子28-2:

include "stdio.h"

int main()
{

char s1[] = {'H','e','l','l','o'};
int i = 0;
char s2[] = {'W','o','r','l','d'};
char* p0 = s1;
char* p1 = &s1[3];
char* p2 = s2;
int* p = &i;

printf("%d\n",p0 - p1); //ok,-3 下标值相减
//printf("%d\n",p0 + p2); //error 仅支持减法
printf("%d\n",p0 - p2); //error  无意义,不指向同一数组元素
//printf("%d\n",p0 - p);  //error 定义类型不同
//printf("%d\n",p0 * p1); //error 仅支持减法
//printf("%d\n",p0 / p1); //error 仅支持减法

}
输出结果:
-3
28

补充:

define countof(a) (sizeof(a)/sizeof(*(a))) 计算数组内的成员个数

a 是一个int型数组,有10个元素,sizeof(a)  就是 a数组整个的存储字节数,10*4=40
*a相当于a[0],  数组第一个元素,
sizeof(*a)  就相当于sizeof(a[0]) =4。
sizeof(a) / sizeof(*(a))=10

例子28-3:

include "stdio.h"

define DIM(a) (sizeof(a) / sizeof(*a))

int main()
{

char s[] = {'H','e','l','l','o'};
char* pBegin = s;
char* pEnd = s + DIM(s);
char* p = NULL;
printf("pBegin = %p\n",pBegin);
printf("pEnd = %p\n",pEnd);
printf("Size: %d\n",pEnd - pBegin);
for(p = pBegin; p < pEnd; p++)
{
    printf("%C",*p);
}
    printf("\n");
    return 0;

}
输出结果:
pBegin = 008FFB34
pEnd = 008FFB39
Size: 5
Hello

注释:
1.pEnd = s + DIM(s);
s + 5 = 008FFB34 + 5 sizeof(s) = 008FFB34 + 5 sizeof(char) = 008FFB34 + 5 1 = 008FFB39 (结果相同)
2.pEnd指向最后一个元素的下一个

小结:
·数组声明时编译器自动分配一片连续的内存空间
·指针声明是只分配了用于容纳地址值的4字节空间
·指针和整数可以进行运算,其结果为指针
·指针之间只支持减法运算,其结果为数组元素下标值
·指针之间支持比较运算,其类型必须相同

点赞
收藏
评论区
推荐文章
似梦清欢 似梦清欢
2年前
排序算法(简单选择、堆排序、归并)
简单选择排序:::tip简单选择排序原理:将未排序的数组中从前向后遍历,找到最小的元素和数组中第一个元素交换位置,此时数组中第一个元素位置已经确定,再将未排序的数组中从前向后遍历,找到最小的元素和数组中第二个元素交换位置,依次向下。:::需要两层循环,外层
Wesley13 Wesley13
3年前
PTA1
11数组定义中,数组名后是用方括号括起来的常量表达式,不能用圆括号。(1分)\T\F12在C语言中能逐个地使用下标变量,也能一次引用整个数组。(1分)T\F\因为它有首地址13同一个数组中的每个元素都具有相同的数据类型,有统一的标识符即数组名,用不同的序号即下标来区分数组中的各元素。(1分)\T\F14数
Souleigh ✨ Souleigh ✨
4年前
JS 实现单链表
要存储多个元素,数组(或列表)可能是最常用的数据结构。但这种数据结构有一个缺点:(在大多数语言中)数据的大小是固定的,从数组的起点或中间插入或移除项的成本很高。  链表存储有序的集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成。  相对于传统的数组,链表的一个好处是
Kevin501 Kevin501
4年前
Go语言中new()和make()的区别
1.Go语言中的值类型和引用类型值类型:int,float,bool,string,struct和数组(数组要特别注意,别搞混了)变量直接存储值,分配栈区的内存空间,这些变量所占据的空间在函数被调用完后会自动释放。引用类型:slice,map,chan和值类型对应的指针变量存储的是一个地址(或者理解为指针),指针指向内存中真
Wesley13 Wesley13
3年前
C语言自学《五》
什么是数组数组是一组数目固定、类型相同的数据项数组中的数据称为元素比如longnumbers\10\;方括号中的数字定义了要存放在数组中的元素个数,称为数组维度数组有一个类型,它组合了元素的类型和数组中的元素个数,因此如果两个数组的元素个数、类型相同,这两个数组的类型就相同可以在数组名称后的方括号内使用索引值,索引值是从0开始
Wesley13 Wesley13
3年前
GNU C 与 ANSI C的区别
1.零长度数组GNUC允许使用零长度数组,定义变长度对象时比较方便structvar\_data{   intlen;   chardata\0\;};var\_data的大小仅为一个int型,data是常量地址,data\index\是访问其后的内存空间。structvar\_data\smal
Wesley13 Wesley13
3年前
Java数组的声明与创建
今天在刷Java题的时候,写惯了C发现忘记了Java数组的操作,遂把以前写的文章发出来温习一下。首先,数组有几种创建方式?Java程序中的数组\\必须先进行初始化才可以使用,\\所谓初始化,就是为数组对象的元素分配内存空间,并为每个数组元素指定初始值,而在Java中,数组是静态的,数组一旦初始化,长度便已经确定,不能再随意更改。
Wesley13 Wesley13
3年前
C#图解教程 第十二章 数组
数组数组数组实际上是由一个变量名称表示的一组同类型的数据元素。每个元素通过变量名称和一个或多个方括号中的索引来访问:数组名索引↓↓MyArray4定义让我们从C中与数组有关的重要定义开始元素数组的独立数据项称为元素。数组的所有元素必须
菜园前端 菜园前端
2年前
什么是链表?
原文链接:什么是链表?链表是有序的数据结构,链表中的每个部分称为节点。可以首、尾、中间进行数据存取,链表的元素在内存中不必是连续的空间,每个节点通过next指针指向下一个节点。优点链表的添加和删除不会导致其余元素位移。缺点无法根据索引快速定位元素。数组和链
小万哥 小万哥
1年前
C++ 获取数组大小、多维数组操作详解
获取数组的大小要获取数组的大小,可以使用sizeof()运算符:示例cppintmyNumbers510,20,30,40,50;cout<<sizeof(myNumbers);结果:cpp20为什么结果显示为20而不是5,当数组包含5个元素时?这是因
深度学习 深度学习
1星期前
LeetCode 2576题解:双指针法求解最多标记下标(排序+贪心策略)
一、题目解读2576题要求在一个整数中寻找最多可标记的下标对:若nums法”的组合思路:1.排序预处理:对原数组nums进行升序排序,确保相同元素聚集,便于后续配对。2.双划分:将排序后的数组分为左右两半(左指针left0,右指针rightn/2),从