#include <stdio.h>
int main()
{
char a[5];
double b[5];
printf("a->%p,a[0]->%p,a[1]->%p,a[2]->%p,a[3]->%p,a[4]->%p\n", a,&a[0],&a[1],&a[2],&a[3],&a[4]);
printf("b->%p,b[0]->%p,b[1]->%p,b[2]->%p,b[3]->%p,b[4]->%p\n", b, &b[0], &b[1], &b[2], &b[3], &b[4]);
}
数组名中保存的是数组第一个元素的地址,数组是一块连续的内存中间,char类型在内存中占一个字节,所以数组中的元素,在内存地址依次递增一位,即一个字节;
double类型的值,在内存中占8个字节,地址以十六进制显示,如果第一个double类型的元素在内存中的地址是000,那么第二个元素在内存的地址是008,第三个是010以此类推;
#include <stdio.h>
int main()
{
int a[5];
int *p = a;
int *p1 = &a[0];
printf("%p,%p,%p", a, p, p1);
}
因为数组名中存放的就是数组的首地址,所以将一个数组放到一个指针变量中,不需要取地址符&;如果是将数组中某个元素的地址赋值给一个指针,则需要取地址符;
#include <stdio.h>
int main()
{
int a[5] = { 111,222,333,444,555 };
int *p = a;
printf("数组第四个元素的地址:%p\n", &a[3]);
printf("数组移动3位的地址:%p\n", a + 3);
printf("指针移动3位的地址:%p\n", p + 3);
printf("显示指针移动3位后内存中的值:%d", *(p + 3));
}
通过对指针加减,可以移动指针指向的地址,int类型的指针,所以每次加1或减1,就会向后或向前移动四个字节;
int类型数组的首地址为99870FF5C8,向后移动到下一个数据,就要移动4个字节,下一个元素的地址就是8+4=16#C;所以第二个元素的地址就99870FF5CC;
使用指针可以访问内存中任意的一个地址中的值,p-1,是数组a[0]上一个地址中值,这个地址中值是没有定义和初始化的值,这个地址可能是被系统中其他程序所使用的,如果修改的这个值,就有可能造成其他程序出现问题;
指针在加1和减1的时候,移动的多少,都是根据定义指针时候的数据类型的的长度,这个长度可以用sizeof来获取;
#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "hello world";
char* p = str;
*(p + 6) = 'W';
*(p + 7) = 'O';
*(p + 8) = 'R';
*(p + 9) = 'L';
*(p + 10) = 'D';
int length = strlen(str);
for (int i = 0; i < length; i++)
{
printf("%c", str[i]);
}
}
通过指针修改数组中的值;
也可以通过指针来获取地址中的值;
指针和数组的区别,虽然通过指针和数组的移动,都可以获得移动后的元素;
数组名是一个地址常量,是不可以进行修改的;
#include <stdio.h>
#include<string.h>
int main()
{
char str[] = "hello world";
char* p = str;
*(p + 6) = 'W';
*(p + 7) = 'O';
*(p + 8) = 'R';
*(p + 9) = 'L';
*(p + 10) = 'D';
int length = strlen(str);
printf("开始时指针指向的地址:%p\n", p);
for (int i = 0; i < length; i++)
{
printf("%c", *(p++));
}
printf("\n结束时指针指向的地址:%p\n", p);
}
指针的值是可以修改的,通过自加的方式,在结束的时候,指针中所存放的地址已经更改了;
#include <stdio.h>
int main()
{
char str[] = "hello world";
char* p = str;
printf("%c", p[4]);
}
指针也可以用下标的方式获取从首地址后第几个元素的值;