数组与指针
来源:互联网 发布:php 商城怎么删除订单 编辑:程序博客网 时间:2024/06/12 19:32
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组(指针的含义包含大小方面,即由指针类型指定)。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。注:此数组每一个元素都是一个指针
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。
这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
还需要说明的一点就是,同时用来指向二维数组时,其引用和用数组名引用都是一样的。
比如要表示数组中i行j列一个元素:
*(p[i]+j)、*(*(p+i)+j)、(*(p+i))[j]、p[i][j]
优先级:()>[]>*
注意:在实际应用中,对于指针数组,我们经常这样使用:
typedef
int
* pInt;
pInt a[4];
这跟上面指针数组定义所表达的意思是一样的,只不过采取了类型变换。
- #include <stdio.h>
- int main(void)
- {
- int i;
- int a[5] = {1, 2, 3, 4, 5};
- int *p = a; //此处p是指向一个int型数据的地址,而a是一维数组第一个元素的地址,所以两个地址对应的
- //数据类型是一致的(包括大小都是一个),所以可以直接赋值。
- for( i = 0; i < 5; i++ )
- printf( "%d\n", *(p + i) );
- return 0;
- }
- int a[2][5] = {1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10};
- #include <stdio.h>
- int main(void)
- {
- int i;
- int a[2][5] = {1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10};
- int (*p)[5] = a;
- for( i = 0; i < 5; i++ )
- printf( "%d\n", *(*p + i) );
- return 0;
- }
- #include <stdio.h>
- int main(void)
- {
- int i;
- int a[2][5] = {1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10};
- int *p = a[0];
- for( i = 0; i < 10; i++ )
- printf( "%d\n", *(p + i) );
- return 0;
- }
- 附:这里的a[0]却输出了hello
- int main(void)
- {
- char a[2][10] = {"hello", "hi"};
- printf( "%s\n", a[0] );
- //printf( "%s\n", *a );
- //printf( "%s\n", *a + 1 ); 输出 "ello"
- //printf( "%s\n", *(a + 1) ); 输出 "hi"
- return 0;
- }
(4)a 和&a 之间的区别(重点)
举个例子:
int *ptr = (int*)(&a + 1);
printf("%d, %d", *(a + 1), *(ptr - 1));
这里的输出的值应该是?
结果是:2,5
原因:
&a 是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。所以 &a 的每次偏移是移动整个内存块(即整个数组)的大小,这里就是移动 sizeof(a),即40 byte,所以这里的 &a + 1, 是指针向下移动个40byte(数组内存块的大小),&a+1的指向 是下个 sizeof(a)大小的内存块。而a+1是移动到数组的第二个元素位置。
在C 语言里,赋值符号“=”号两边的数据类型必须是相同的,如果不同需要显示或隐式的类型转换。ptr 这个定义的“=”号两边的数据类型不一致,左边的类型是指向整个数组(5个int)的指针,右边的数据类型是指向单个int的指针,所以采用强制转换(int*),这时指针的偏移是按照转化后的类型来进行的,所以减1,即地址向低偏移4字节(一个int元素)指向5对应地址。
- #define FD 5
- // ...
- int a[3+2],b[7+FD];
- int n=5;
- int a[n];
- int a,b,c,d,k1[10],k2[20];
类型说明符 数组名[常量表达式] = { 值, 值……值 };
其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。例如:
- int a[10]={ 0,1,2,3,4,5,6,7,8,9 };
a[0]=0; a[1]=1 ... a[9]=9;
C语言对数组的初始化赋值还有以下几点规定:
1) 可以只给部分元素赋初值。当{ }中值的个数少于元素个数时,只 给前面部分元素赋值。例如:
- int a[10]={0,1,2,3,4};
2) 只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为:
- int a[10]={1,1,1,1,1,1,1,1,1,1};
- int a[10]=1;
3)如给全部元素赋值,则在数组说明中,可以不给出数组元素的个数【单纯定义时(不初始化): int a[ ] ; 是错误的】例如:
- int a[5]={1,2,3,4,5};
- int a[]={1,2,3,4,5}; 定义的同时初始化
- 指针:指针与数组
- 指针与指针数组
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 数组指针与指针数组
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组与数组指针
- 指针数组 与数组指针
- 指针数组与数组指针
- 数组指针与指针数组
- 指针数组与数组指针
- 指针数组与数组指针
- tjut 3584
- Python for Data Analysis (5)
- 167. Two Sum II - Input array is sorted
- [Android] 实时动态监测网络变化
- SFDC 测试类注意事项
- 数组与指针
- Hibernate学习笔记:难点,常见面试题
- ios键盘的第一响应者和打开关闭触发的通知
- BGRABitmap图像操作9d:渲染前面的水纹
- WebService理解和代码解析
- 关于计算机视觉的各种库儿们
- 微信退款
- js实现百叶窗
- 99 Problems in Scala