总结一些关于指针和数组的知识点
指针理解
指针的值和指针的地址
#include <stdio.h>
int main()
{
int var = 10;
int *ptr_var;
ptr_var = &var;
printf("var的值是:%d\n",var);
printf("var的内存地址是:%x\n",&var);
printf("指针 ptr_var的内存地址是:%x\n",&ptr_var);
printf("var 的值是:%d\n",*ptr_var);
printf("var 的地址是:%x\n",ptr_var);
return 0;
}
运行结果
var的值是:10
var的内存地址是:5fbff7b8
指针 ptr_var的内存地址是:5fbff7b0
var 的值是:10
var 的地址是:5fbff7b8
从以上代码的运行结果可以看出,无论是指针变量还是普通变量,都有其固定的地址。指针变量的地址是内存中的一片空间,指针变量的值是其所指向变量的地址。通过这个地址可以访问变量的内容,即通过指针访问变量的内容。
一维数组常见的访问方式
#include <stdio.h>
int main()
{
int array[10]={1,2,3,4,5,6,7,8,9,0};
printf("array =%p\n",array);
printf("&array[0]=%p\n",&array[0]);
int *p = array;
for (int i=0; i<10; i++) {
printf("array[%d] = %d\n",i,*(p+i));
}
printf("****************\n");
for (int i=0; i<10; i++) {
printf("array[%d]=%d\n",i,*p);
p++;
}
printf("****************\n");
int *q = array;
for (int i=0; i<10; i++) {
printf("array[%d] = %d\n",i,*q++);
}
return 0;
}
二维数组的理解
二维数组表示的数据结构是二维的,但是计算机本身的储存方式是线性的,也就是说数据在内存中存储的方式仍然是线性的。
#include <stdio.h>
int main()
{
int a[3][4] = {{1,2,3,4},{10,20,30,40},{100,200,300,400}};
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
printf("%p ",&a[i][j]);
}
putchar('\n');
}
printf("*******************\n");
printf("a =%p\n",a);
printf("a+0=%p\n",a+0);
printf("a+1=%p\t",a+1);printf("(a+1)+1=%p\n",(a+1)+1);
printf("a+2=%p\n",a+2);
printf("*******************\n");
printf("a[0] = %p\n",a[0]);
printf("a[1] = %p\t\t",a[1]);
printf("a[1]+1 =%p\t",a[1]+1);
printf("*(a[1]+1)=%d\t",*(a[1]+1));
printf("*(*(a+1)+1)=%d\n",*(*(a+1)+1));
printf("a[2] = %p\n",a[2]);
printf("********************\n");
printf("a+1 =%p\n",a+1);
printf("(a+1)+1=%p\n",(a+1)+1);
printf("*(a+1)+1=%p\n",*(a+1)+1);
printf("a[1] = %p\n",a[1]);
printf("a[1]+1=%p\n",a[1]+1);
printf("&a[1]+1=%p\n",&a[1]+1);
return 0;
}
运行结果:
0x7fff5fbff780 0x7fff5fbff784 0x7fff5fbff788 0x7fff5fbff78c
0x7fff5fbff790 0x7fff5fbff794 0x7fff5fbff798 0x7fff5fbff79c
0x7fff5fbff7a0 0x7fff5fbff7a4 0x7fff5fbff7a8 0x7fff5fbff7ac
*******************
a =0x7fff5fbff780
a+0=0x7fff5fbff780
a+1=0x7fff5fbff790 (a+1)+1=0x7fff5fbff7a0
a+2=0x7fff5fbff7a0
*******************
a[0] = 0x7fff5fbff780
a[1] = 0x7fff5fbff790 a[1]+1 =0x7fff5fbff794 *(a[1]+1)=20 *(*(a+1)+1)=20
a[2] = 0x7fff5fbff7a0
********************
a+1 =0x7fff5fbff790
(a+1)+1=0x7fff5fbff7a0
*(a+1)+1=0x7fff5fbff79
a[1] = 0x7fff5fbff790
a[1]+1=0x7fff5fbff794
&a[1]+1=0x7fff5fbff7a0
可以看到,二维数组的地址分配是连续的。从0x7fff5fbff780
到0x7fff5fbff7ac
。
a是数组首元素的地址,所以a的值和&a[0]的值相同,另一方面,a[0]本身是包含4个整数的数组,因此,a[0]的值同其首元素的地址&a[0][0]相同。简单的讲,a[0]是一个整数大小对象的地址,而a是4个整数大小对象的地址。因为整数和4个整数组成的数组开始于同一个地址,因此a和a[0]的值是相同的。
a所指的对象大小是4个int,而a[0]所指的对象大小一个int,因此,a+1和a[0]+1 的结果是不同的。