【C语言学习】指针再学习(二)之数组的指针

★一维数组

一个整型数据为4个字节。4个字节就是32位,即可以表示2^32个数字

在程序中定义一个数组a[5] = {1,2,3,4,5};

那么a[0]的地址就是0x00000000,数组名a是数组首元素的地址,a的地址也是0x00000000。a+1则表示的地址是0x00000004,而不是0x00000001。因为1这个值,根据前面的指针a所指向的类型的长度来调整自己的长度。也就是说如果a是指向整型的指针,那么后面加的1也表示4个字节,如果a是指向字符型的指针,那么后面加的1表示1个字节。

★数组的指针

定义一个二维数组a[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};

那么a 的类型是“指向包含5个整型元素的数组的指针”,也就是指向上面数组的第一行,,那么表达式a + 1,它的类型也是“指向包含5个整型元素的数组的指针”,它指向的是第二行,这就是因为1,它就是根据前面a的类型的长度来调整。可以将二维数组看做一维数组,只有三个元素,分别是:a[0]、a[1]、a[2]。只不过,这三个元素不是一个值,而是一个数组。数组名a指向的是a[0](即指向的是一个包含5个元素数组)a+1指向的是a[1]。又因为*(a
+ 0)等价于a[0](找了好多本书一直没有弄明白为什么。谭浩强书上这样解释:*(a + 0)并不是a+0单元的内容,因为a+0并不是一个变量的存储单元。*(a+0)就是a[0],而a[0]是一维数组名,所以也是地址,指向a[0][0]),a[0]是一维数组(a[0]中包含的5个元素)的首元素的地址,就是a[0][0]的地址。因此a[0]+1就是a[0][1]的地址,*(a[0] +1)就是a[0][1]。所以将a[0][1]展开就是*(*(a + 0)+1)。

a表示的就是一个指向整型数组的指针,它的声明: int (*p)[5];这表示的就是p是一个指针,它指向一个整型元素个数为5的数组。

★int *ptr=(int *)(&a+1)问题

在网上有这样一道面试题目

main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d,%d",*(a+1),*(ptr-1));
}

它的结果是2,5

对于第一个输出应该很简单,基本上没有什么疑问,关键就是第二个输出,它为什么会输出5呢?这里面的难点就是对&a的理解。

这里面就涉及到数组的指针问题。a是一维数组的首元素的地址,&a的含义(*(a+0)<==> a[0]):就相当于上面二维数组中对a[0]取地址,得到的是二维数组的a,就是一个指向有5个元素的数组的指针。那么&a+1,指向的是下一个5个元素的数组,那么指针ptr指向的就是a[4]后面的内存单元,而ptr-1就是指向的是a[4],*(ptr-1)就是a[4]的值。

【C语言学习】指针再学习(二)之数组的指针,布布扣,bubuko.com

时间: 2024-07-30 10:19:00

【C语言学习】指针再学习(二)之数组的指针的相关文章

黑马程序员——c语言学习心得——函数传递二维数组

黑马程序员——c语言学习心得——函数传递二维数组 -------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.定义指针的时候一定要初始化.   变量定义的时候给变量初始化,这是保证不出错的一个很好的习惯.尤其是在指针的使用上,如果我们没有给指针初始化,就会出现野指针,该指针的指向并不是我们所希望的,一旦错误的释放了这个指针,就会发生内存的访问.那么如何初始化指针变量呢,一般有以下几种方法:   1.初始化空指针   int* pInteger=N

《Javascript权威指南》学习笔记之十二:数组、多维数组和符合数组(哈希映射)

Array(数组)是JavaScript中较为复杂的数据类型,同Java.C#.VB等程序语言的数组相比,Javascript数组中的元素不必为相同的数据类型,可以在数组每个元素上混合使用数字.日期.字符串.Object,甚至添加一个嵌套数组. 一.创建数组 1.var arr1 = new Array(); /var  arr2 = new Array(length); /var arr3 = new Array(element1,element2...); var arr4 = [eleme

程序猿之--C语言细节13(二维数组和指针,&amp;*a[i][0]的理解,数组1[e]和e[1]很可能你没见过)

主要内容:二维数组和指针,&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

C语言 二维数组与指针笔记

今天分析了C语言二维数组和指针的基本理解,感觉有点懵...代码记录一下,如果有大神临幸发现哪里有误,欢迎指正~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> //void func(int p[][]) //这样写等同于void func(int **p) p++移动了四个字节,(*p)++移动了四个字节,不符合二维数组规律 //{ //} //列优先输出的函数(即竖着输出) void func

程序员之--C语言细节13(二维数组和指针,&amp;amp;*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)

主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

C语言 二维数组(指针)动态分配和释放(转)

C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按照16位.32位.64位为单位进行编辑的话:旧的16位处理器,比如Intel 80286 CPU需要8个指令,32位的处理器需要4个指令,而64位处理器则只要两个指令,显然,在工作频率相同的情况下,64位处理器的处理速度会比16位.32位的更快.而且除了运算能力之外,与32位处理器相比,64位处理器

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

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

c语言中如何通过二级指针来操作二维数组

通过二级指针去访问二维数组需要先给二级指针分配等同于二维数组行数的一维数组指针,然后把二维数组的每行首地址赋值给对应位置的一维指针上.之后就可以通过二维指针直接访问了. 参考代码如下,可以看具体注释辅助理解. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h>//输入输出头文件. #include <stdlib.h>//本程序需要用到malloc/free函数,引

对二维数组使用指针进行操作的探索(C语言)

1 /* 2 Name: 对二维数组使用指针进行操作的探索 3 Copyright: 4 Author: lingr7 5 Date: 01/12/18 11:55 6 Description: 7 */ 8 #include<stdio.h> 9 int main() { 10 11 int a[2][3] = {{1,2,3},{4,5,6}}; 12 int **p = a;/*这一步,将a存放的地址赋值给了p,这一步是的p与a完全等价*/ 13 int *p2 = p;/*这一步就将a