数组(一维和二维)与指针(C语言)
2016-12-06 16:04
375 查看
一指向一维数组的指针
1使指针指向数组首地址的方法
2通过指针引用一维数组元素
二二维数组与指针
1先重新认识一下二维数组
三指向数组的指针变量指向二维数组某一行
读者,你好!
如果你精通C,希望能得到你的斧正;如果你是初学者,希望能对你有所帮助。
加粗的是一些我认为比较重要的内容。
C语言规定,数组名代表数组首地址,因此用“pa = a”表示将数组a首地址传给指针pa,而如果用”pa = &a”,的形式就是错误的。这里要注意数组名和普通变量名的差别。
①下标法:a[0], a[1],……….a[i];
②指针法间接访问:*p, *(p+1),………*(p+i);
数组指针变量向前或向后移动一个位置和地址加1或减1的概念不同,因为数组可以有不同类型,各种类型的数组元素所占的字节长度是不同的,指针变量向前或向后移动一个位置就是变量减1或加1,即指向下一个数据元素的首地址。而不是在原有的地址基础上加上1。
数组元素a[i]及其地址的表示法:
特别注意这里的i是指数组元素的偏移量,而不是说实际地址加i。
代码验证如下:
运行结果:
注意:若将上述算法中的 c = *(p+1);改为
如何用指针实现数组的输入与输出。具体算法如下:
注意事项:
输入时是
对于三个元素A[0],A[1],A[2]又是三个一位数组名,也就是三个地址,即都是指针,分别指向三个数组的首元素,即A[0][0], A[1][0], A[2][0]。
比如现在要访问元素A[1][3],有下列几种方法:
①就是直接用二维数组下标法:A[1][3]。
②用一维数组名的方法:
③用二维i数组名的方法, 只要②中的一维数组名改成相应的二维数组名即可:比如把A[1]改成
④还可以用
先看一下列子
运行结果为:
从上述结果可以看出,&A[0][0], A[0], A,都指向元素A[0][0], 但是要真正访问该地址所存的内容时,应该
访问一个二维数组元素的通用公式:
先说明一点, A[i]无条件等于
所以我们为了让“二维数组名+1” 指向二维数组的下一行,考虑是否定义一种特别的指针, 当该指针加一时能指向二维数组下一行,而不是下一个元素。下面让我们来定义一个这样的指针。
指向数组的指针变量的定义和使用
这里需要注意的是,定义方式
有了上面的定义,二维数组各元素的地址可以通过指针p来表示。For example:
当然这里也可以直接用二维数组名表示,比如
运行结果为:
1使指针指向数组首地址的方法
2通过指针引用一维数组元素
二二维数组与指针
1先重新认识一下二维数组
三指向数组的指针变量指向二维数组某一行
读者,你好!
如果你精通C,希望能得到你的斧正;如果你是初学者,希望能对你有所帮助。
加粗的是一些我认为比较重要的内容。
一、指向一维数组的指针
1、使指针指向数组首地址的方法
int a[5]; //整型数组 int *pa; //整形指针,可以指向整型数组 pa = a; //把数组a的首地址赋给pa pa = &a[0]; //把数组a的首元素地址的地址赋给pa
C语言规定,数组名代表数组首地址,因此用“pa = a”表示将数组a首地址传给指针pa,而如果用”pa = &a”,的形式就是错误的。这里要注意数组名和普通变量名的差别。
2、通过指针引用一维数组元素
把数组的首地址传给指针变量的形式称为“地址传递”,地址传递以后,数组和指针就可以“共享”一段数组空间。因此访问数组元素的内容,就有两种方式:①下标法:a[0], a[1],……….a[i];
②指针法间接访问:*p, *(p+1),………*(p+i);
数组指针变量向前或向后移动一个位置和地址加1或减1的概念不同,因为数组可以有不同类型,各种类型的数组元素所占的字节长度是不同的,指针变量向前或向后移动一个位置就是变量减1或加1,即指向下一个数据元素的首地址。而不是在原有的地址基础上加上1。
数组元素a[i]及其地址的表示法:
表示方法 | 元素 | 地址 | 说明 |
---|---|---|---|
下标法 | a[i] | &a[i] | 下标法 |
指针下标法 | p[i] | &p[i] | 下标法 |
地址法 | *(a+i) | a+i | 指针法 |
指针法 | *(p+i) | p+i | 指针法 |
代码验证如下:
#include <stdio.h> int main() { int a[10] = {1,2,3,4,5,6,7,8,9,0} , b, c, d, e; int *p = &a[0]; b = *(a + 1); c = *(p + 1); d = a[1]; e = p[1]; printf("*(a + 1) = %d\n *(p + 1) = %d\na[1] = %d\np[1] = %d\n", b, c, d, e); }
运行结果:
注意:若将上述算法中的 c = *(p+1);改为
c = (*P)+1;那么输出结果是完全不同的,(*p)+1;意思是取P这个地址所存的数据,再给这个数据加一,按照算法,c = 3。而如果使用p++,又会怎样呢?比如
p += 3那么此时p指向的是数组第4个元素的地址,此时p[0]就是a[3]了,也就是 4,而票p[-1]就是a[2]。
如何用指针实现数组的输入与输出。具体算法如下:
#include <stdio.h> int main() { int arr[4] = {0}, counter; int *pa = arr; for(counter = 0;counter <= 3; counter++) { scanf("%d",pa++); } pa--; for(counter = 3; counter >= 0;counter--) { printf("%d ", *pa--); } }
注意事项:
输入时是
scanf("%d", pa++);而输出时是
printf("%d", *pa--);输入时要存一个数据,所以必须先取得内存地址,而输出时是一个整数,要知道这个内存空间所存的数据具体是什么。
二、二维数组与指针
1、先重新认识一下二维数组
二维数组可以看做是一维数组的数组,列如对于二维数组int A[3][4];可以把 A看作是由3个一维数组元素组成的。即A由A[0], A[1], A[2]组成,而A[i]都是长度为4的一维数组。
对于三个元素A[0],A[1],A[2]又是三个一位数组名,也就是三个地址,即都是指针,分别指向三个数组的首元素,即A[0][0], A[1][0], A[2][0]。
比如现在要访问元素A[1][3],有下列几种方法:
①就是直接用二维数组下标法:A[1][3]。
②用一维数组名的方法:
*(A[1] +3);或
*(A[0]+7);当然也可以是
*(A[2]-1);
③用二维i数组名的方法, 只要②中的一维数组名改成相应的二维数组名即可:比如把A[1]改成
*(A+1)这样就可以得到如下访问方式:
*(*(A+1)+3)或
*((*A)+7)或
*(*(A+2)-1).一般情况下不用这种方法,过于繁琐。
④还可以用
*和
&运算符来访问,
*(&A[1][3]),,同理也可以用
&A[0][0]来代替A[0]。
先看一下列子
#include <stdio.h> int main() { int A[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}},i = 0, j = 0; for(i = 0;i < 3; i++) { for(j =0;j < 4 ; j++) { printf("&A[%d][%d] = %p ", i, j, &A[i][j]); } printf("\n"); } printf("\n&A[0][0] = %p\n", &A[0][0]); printf("*(&A[0][0]) = %d\n", *(&A[0][0])); printf("&A[0] = %p\n", &A[0]); printf("A = %p\n", A); printf("&A = %p\n", &A); printf("*A = %d\n", *A); printf("**A = %d\n", **A); printf("A[0] = %p\n", A[0]); printf("*A[0] = %d\n", *A[0]); return 0; }
运行结果为:
从上述结果可以看出,&A[0][0], A[0], A,都指向元素A[0][0], 但是要真正访问该地址所存的内容时,应该
*A[0], **A, 而不能是
*A, 因为
*A访问的是A所存的内容,A中存的是A[0][0] 的地址。
访问一个二维数组元素的通用公式:
int A[M][N] = {}; int *pa = A; pa = pa + i * N + j; //访问元素A[i][j]。 printf("%d", *pa);
三、指向数组的指针变量指向二维数组某一行
这部分内容与上面的有点重复,但是为了更好地理解,我还是要写。先说明一点, A[i]无条件等于
*(A+i)
所以我们为了让“二维数组名+1” 指向二维数组的下一行,考虑是否定义一种特别的指针, 当该指针加一时能指向二维数组下一行,而不是下一个元素。下面让我们来定义一个这样的指针。
指向数组的指针变量的定义和使用
语法 | 样列 | 说明 |
---|---|---|
数据类型(*指针变量名)[m]; | int A[3][4];int (*p)[4]; p = A; | 定义指针变量,指向由m个某数据类型元素组成的一维数组。圆括号不能丢失,否则变成“指针数组” |
int (*p)[M];①M是指该数组的列数。②不要忘了圆括号
(*p)。
有了上面的定义,二维数组各元素的地址可以通过指针p来表示。For example:
*(p+0)+0 | *(p+0)+1 | *(p+0)+2 | *(p+0)+3 |
---|---|---|---|
*(p+1)+0 | *(p+1)+1 | *(p+1)+2 | *(p+1)+3 |
*(p+2)+0 | *(p+2)+1 | *(p+2)+2 | *(p+2)+3 |
*(p+0)+1可以写成是
*(A+0)+1。下面代码验证这两种情况:
/*This program is used to find the max in each row of a matrix*/ #include <stdio.h> #define M 3 #define N 4 int main() { int A[M] , i, j, max; int (*p) ; p = A; for(i = 0; i < M;i++) { for(j = 0;j < N;j++) { scanf("%d", &A[i][j]); } } printf("--------matrix-------\n"); for(i = 0; i < M;i++) { printf("row %d: ", i); for(j = 0;j < N;j++) { printf("%3d", *(*(A+i)+j)); } printf("\n"); } printf("\n"); for(i = 0;i < M;i++) { max = A[i][0]; for(j = 0; j < N;j++) { if(max < *(*(p + i)+j)) { max = *(*(p + i)+j); } } printf("row %d :max = %d\n", i, max); } return 0; }
运行结果为:
相关文章推荐
- 一维指针和数组,二维指针和数组
- C语言malloc函数为一维,二维,三维数组分配空间
- C语言 通过指针访问一维数组的几种方式,通过数组名访问一维数组
- 【C语言】-指向一维数组元素的指针
- C语言-指向一维数组元素的指针
- 指针和数组(一维,二维,三维)以及野指针的避免
- c语言中指针,二维数组,一维数组,指针数组,二级指针,应用
- 【C语言】12-指向一维数组元素的指针
- C语言——数组与指针之动态分配一维和多维数组
- C语言中一维指针与二维指针的转化
- 【C语言】12-指向一维数组元素的指针
- 黑马程序员——C语言之字符串指针与二维字符串数组
- 一维/二维动态数组分配(C语言)
- C语言 指针与一维数组,指针遍历一维数组的多种方法
- 【C语言】12-指向一维数组元素的指针
- 【C语言】12-指向一维数组元素的指针
- 【C语言】12-指向一维数组元素的指针
- 【C语言】12-指向一维数组元素的指针
- C++(typedef、一维数组转成二维数组、C和C++区别、成员地址成员指针、构造析构函数、this指针、const用法、显示时间、const用法)
- 【C语言】12-指向一维数组元素的指针