数组与指针
2017-03-17 11:35
225 查看
数组
数组是指具有相同类型的数据组成的序列,是有序集合。(教科书上的定义)即:数组就是内存中一段连续的存储空间。那么我们怎么使用它呢?用数组名。也就是我们用数组名可以在内存中找到对应的数组空间,即数组名对应着地址。对应着首元素的地址,所以,我们可以通过数组的首元素地址来找到数组
数组名是一个地址(首元素地址),即是一个指针常量。
只有在两种场合下,数组名并不用指针常量来表示:
1. sizeof(数组名) ; sizeof返回整个数组的长度,而不是指向数组的指针长度。
2. &数组名 ; 产生的是一个指向整个数组的指针,而不是一个指向某个指针常量的指针。
&a[0] 与 &a 的区别:
两者的值相同,但意义不同。
&a[0]是指数组首元素的地址。&a是整个数组的地址。两者的值相同。
a+1 与 &a+1 的区别:
数组名a除了在上述两种情况下,均用&a[0]来代替。
a+1即等同于&a[0]+1。注意:指针(地址)与常数相加减,不是简单地算术运算,而是以当前指针指向的对象的存储长度为单位来计算的。
即:指向的地址+常数*(指向的对象的存储长度)
&a[0]为数组首元素的地址。
故&a[0]+1 越过一个数组元素长度的位置。即:&a[0]+1*sizeof(a[0])。
&a为整个数组的地址。(只是用首元素地址来表示,其实际代表的意义是整个数组)
故&a+1 越过整个数组长度的位置,到达数组a后面第一个位置。 即:&a+1*sizeof(a)。
指针
指针与取地址#include<stdio.h> #include<stdlib.h> int main() { int *a = (int*)malloc(sizeof(int)); *a = 1; printf("\na = %d", *a); printf("\na heap address = %p", a); printf("\n&a stack address = %p", &a); printf("\n"); }
结果如下(程序打印出的结果不尽相同):
a = 1 a heap address = 0x7fd67bc000e0 &a stack address = 0x7fff528d8ac8
第一行表示 变量a的值为1
第二行表示 变量a所存储的内存地址0x7fd67bc000e0,(存放整数 ‘1’ 所用的4个bytes, 64位机器的话就是8个bytes),这块内存在堆上-heap
第三行表示 变量a本身(一个整数型指针 int* )的内存地址0x7fff528d8ac8,这块内存在栈上-stack。
#include<stdio.h> int main() { int num = 7; int *p = #//初始化指针,也可以写作int* p = # printf("%d 的地址是 %p\n", num, p); return 0; } //7 的地址是 0x7fff5a2d5b28
上面int p定义了一个指向int类型指针p(我们使用符号把p声明为指针),并初始化p使其指向int类型的变量num,这里&num中的&是取地址操作符,当&作用于一个对象上时,它返回了该对象的地址。
所以这里指针p指向了num所对应的地址。
解引用与指针赋值
#include<stdio.h> int main(void) { int num = 7; int *p = # printf("数值%d所在的地址是 %p\n", num, p); printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, *p); *p = 100; printf("指针p所指向的地址为 %p , 该地址上所保存的值为%d\n", p, num); printf("num: %d\n", num); return 0; }
数值7所在的地址是 0x7fff5ce40b28
指针p所指向的地址为 0x7fff5ce40b28 , 该地址上所保存的值为7
指针p所指向的地址为 0x7fff5ce40b28 , 该地址上所保存的值为100
num: 100
注意这里*操作符为解引用操作符,它返回指针p所指的对象(左值)。
我们可以对*p赋值(对左值赋值),从而改变p所指的地址上所保存的值,从而改变此地址所存储的变量num的值。
#include<stdio.h> int main(void) { int num = 7, another = -5; int *p = # p = &another; printf("%d\n", *p);//此时p指向了another,所以输出了another的值,即-5 return 0; } //-5
当然,我们也可以给指针p赋值,使其指向另外一个地址,这样就改变了在解引用时获取的左值。
指针表达式
注意:*与++优先级相同,且它们的结合性都是从右向左的。
例:对于 *cp++ ; 我们可以把它分解为: *cp 之后再 cp++
对于 *++cp ; 我们可以把它分解为:++cp 之后再*cp
数组与指针
#include<stdio.h> int main(void) { int val[100]; for (int i = 0; i < 100; ++i) val[i] = i; int *p = val;///近似理解为 int *p = &val[0]; ///这里发生了隐式指针转换:数组自动转换为指向第一个元素的指针 printf("%d\n", *p); ///指针p指向val的第一个元素,即val[0] int t = 100; while (t--) ///可以直接对指针进行加减运算,就和迭代器一样 printf("%d\n", *(p++));///输出0~99 ///指针可以做差: int *p2 = &val[10], *p3 = &val[20]; printf("%d\n", p3 - p2); //10 printf("%d\n", p2 - p3); //-10 ///还可以比比较大小: printf("%d\n", p2 < p3 ? p3 - p2 : p2 - p3); //10 return 0; }
注意:
两个指针直接相加是不允许的。(你要真想把两个地址值相加,把它们先都强制转换为int型即可)
两个指针直接相减在语法上是允许的。(但必须相对于同一个数组,结果是两指针指向位置相隔的元素个数)
相关文章推荐
- 数组和指针的区别
- 数组名与指针的区别
- 引用数组,指针数组与数组引用,数组指针
- 指针数组 数组指针 函数指针 堆中分配
- 对象数组的指针遍历方案
- 第四章 数组和指针
- 数组指针,指针数组,函数指针,指针函数
- 指针数组&数组指针
- sizeof(数组名)和sizeof(指针)的区别
- 数组的行地址、列地址和指针的应用
- 数组和指针(续)
- C语言之指针和数组 1
- 指针基础知识 ,破坏指针数组的讨论,
- C++指针数组、数组指针、数组名及二维数组详解【转载】
- 数组与指针关系
- delphi里动态数组和指针的运用
- 数组和指针的区别与联系
- 第七章 数组,指针和引用
- c/c++ 函数、常量、指针和数组的关系梳理
- 数组和指针的区别和联系?