C中数组与指针【转】

在这里随便定义一个数组

int arr[5];

arr现在就是数组名, arr 代表的是该数组整块内存,即sizeof(arr) == 20 (假设sizeof(int) == 4), arr 里的内容是该块内存的首地址,即 arr == &arr[0]  。 arr可以看做是一个常量,也就不可以使用 arr++ 之类的运算。

int *p;

p = arr;

p是一个指向int类型的指针,p  = arr,就是把数组的首地址(arr的内容就是数组的首地址,这个前面有分析)赋给p,即 p 现在就是指向数组的首地址,通过 p 就可以访问整个数组,但是 p 这里只是是个指针变量,也就是 p 的本质没有改变,p 不能和 arr 一样代表整个数组的内存, 所以 sizeof(p) == sizeof(int*)  != sizeof(arr)。

把数组的首地址赋给 p,但 p 的本质一个int类型的指针变量,所以也就可以对 p 进行 ++ 之类的运算。

我们可以通过对 p ,arr 的偏移(int类型的指针 +1 或 -1, 是向上或向下偏移 sizeof(int) 个byte)来访问数组里的元素,         *( p + i ) ,*(arr + i),也可以通过传统的 arr[i] 访问数组。

举个例子(例子来源于老师上课时讲解的):

int a[5]  = {1, 2, 3, 4, 5};

int *ptr = (int*)(&a + 1);

printf("%d, %d", *(a + 1), *(ptr - 1));

这里的输出的值应该是?

a 是 代表(不是指向)的是整个数组内存,a 的值是该数组内存的首地址, 对 a 取地址(&a),即......,所以这里的 &a 是指向整个数组的内存块,所以 a 的值与 &a 的值是一样的,都是该数组的首地址,但他们的含义是不一样的。

这里 &a 的每次偏移是移动整个内存块的大小,这里就是移动 sizeof(a),即40 byte,所以这里的 &a + 1, 是指针向下移动个40byte(数组内存块的大小),&a+1的指向 是下个 sizeof(a)大小的内存块。

下面是内存分配图:

&a   ---> ==========  假设这里的地址值是 0x11111111          &a 和 a 的值都是 0x11111111

||        1        ||

==========

||        2        ||

==========

||        3        ||

==========

||        4        ||

========== <-----ptr-1  int类型的指针每偏移是 sizeof(int) 个 字节

||        5        ||

&a +1 ---> ==========  <-----ptr    上面的题目中 让 int 类型的指针 ptr 也指向了这里

||        ?        ||

==========

||        ?        ||

==========

||        ?        ||

==========

||        ?        ||

==========

||        ?        ||

&a+2 ---->==========

||        ?        ||

==========

""""""

""""""

""""""

所以上面题目的输出结果 是 :

2,5

以上都是我个人对于C中指针与数组的理解,若有什么不对的地方,欢迎指出!

时间: 2024-10-08 20:04:59

C中数组与指针【转】的相关文章

C语言中数组与指针

数组是内存空间的一片连续的区域,用于存贮一组相同数据类型元素的集合. 指针变量中存放的是变量的地址,通过指针取得地址,再通过地址提取数据. 在大多是C语言书中,都有这样的说法,“数组和指针是相同的”.其实,数组与指针,只能在特定的情况下才是相同的,在大多书情况下,他们并不相同. C语言中每个表示变量的符号都代表一个地址,而每个变量的值就是该地址里所存储的内容. 定义一个字符数组 char a[]="asdfghjkl";现在来访问第i个字符a[i],编译器符号表中具有一个符号,它代表的

c语言中数组,指针数组,数组指针,二维数组指针

1.数组和指针 int array[5] = {1,2,3,4,5};// 定义数组 // 1. 指针和数组的关系 int * pa = array; pa = array; // p[0] == *(p+0) == array[0] == *(array+0) printf("%p\n", pa); printf("%p\n", array); /* 访问数组两种方式 1. 下标法访问 数组名[下标] 指针[下标] 下标:偏移量 2. 指针法访问 *(p+1) *

C 中数组和指针的区别

联系: 1,一个通过数组和下标实现的表达式可等价地通过指针和偏移量实现. 2,当数组名传递给一个函数时,实际上传递的是该数组第一个元素的地址. 区别: 1,指针是一个变量,因此,在C语言中,语句pa=a和pa++都是合法的.但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的. 2,数组名代表定义的一整块内存,sizeof 得到的是整个数组的字节大小,而指针终究是一个变量,sizeof 得到的是该指针占用的字节数.

由strcat函数引发的C语言中数组和指针问题的思考

问题一 首先,来看一下下面这段代码: #include <stdio.h> #include <string.h> int main() { char *str = "media"; char *tmp = "aaa"; printf("str: %s\n",str); strcat(str,tmp); printf("str: %s\n",str); return 0; } 代码打眼儿一看,功能很明显

数组和指针关系的探讨

在学习过程中,数组和指针的操作几乎完全一样,且不说传数组可以用传指针完全替代,而且指针也可以使用[]操作符来访问指针偏移后的地址,所以在实际应用中数组和指针用不出任何差别.(如下代码所示) #include<iostream> using namespace std; int main() { int a[]={1,2}; cout<<*a<<endl; int* b=a; cout<<*b<<endl; return 0; } 所以人们在实际使

C/C++数组和指针详解

/****************************************************************/ /*            学习是合作和分享式的! /* Author:Atlas                    Email:[email protected] /*  转载请注明本文出处: *  http://blog.csdn.net/wdzxl198/article/details/9087497 /*************************

浅谈C中的数组和指针(二)

原文转载地址:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242419.html 在原文基础上增加自己的理解作为修改 浅谈C/C++中的指针和数组(二) 前面已经讨论了指针和数组的一些区别,然而在某些情况下,指针和数组是等同的,下面讨论一下什么时候指针和数组是相同的. C语言标准对此作了说明: 规则1:表达式中的数组名被编译器当做一个指向该数组第一个元素的指针: 注:下面几种情况例外 1)数组名作为sizeof的操作数 2)使用&

直观理解C语言中指向一位数组与二维数组的指针

一维数组和指针: 对于一位数组和指针是很好理解的: 一维数组名: 对于这样的一维数组:int a[5];  a作为数组名就是我们数组的首地址, a是一个地址常量 . 首先说说常量和变量的关系, 对于变量来说, 用箱子去比喻再好不过了, 声明一个变量就声明一个箱子,比如我们开辟出一个苹果类型的箱子, 给这个变量赋值就是把盛放苹果的箱子中放入一个实实在在的苹果, 这就是变量的赋值.  而对于数组来说, 就是一组类型相同的箱子中,一组苹果箱子, 可以放入不同的苹果. 一维数组空间: 变量被声明后, 我

C语言中的sizeof中的数组和指针

1.引子 今日在看动态规划的0-1背包问题,看完后还是打算自己写着试试,毕竟实践才能出真知嘛.动态规划的结果是个二维数组dp,我copy书上的例子进行初始 memset(dp,0,sizeof(dp)),考虑到程序的健壮性,对于数组我都是用的动态申请,自然二维数组也不例外[动态二维数组的建立可参见本blog的延伸]. 程序写完后,但是却不能运行,开始单步调试,当进行到dp的赋值时老是报指针的错误!!!开始我以为是指针越界什么的,仔细才发现dp的数组维数确实要多申请一个用来存放初始情况的值(全是0