指针和数组

指针也就是地址,他存储的是一个变量在内存中所在的位置,当它存储变量i的地址时,我们就说这个指针指向i

在32位编译器中,指针变量的大小都是4字节,也就是是说int* 和char* 类型的变量都是四个字节

int m;
char n;
int *i;
char *j;
printf("m在内存中占%d个字节\n n在内存中占%d个字节\n",sizeof(m),sizeof(n));
printf("i在内存中占%d个字节\n j在内存中占%d个字节\n",sizeof(i),sizeof(j));
m在内存中占4个字节
n在内存中占1个字节
i在内存中占4个字节
j在内存中占4个字节

 

指针之间的加法乘法除法都是没有意义的,但是指针之间的减法可以表示地址的偏移,比如你的门牌号是123我的门牌号是456,123+456 123*456 123/456都没有任何意义

但是123-456或者456-123的差就可以表示地址的偏移,我们如果知道了这个差值那么我们就可以通过过我的门牌号找到你的门牌号,从而找到你家

我们都知道数组名就是一个指针常量,它存储的是数组第一个元素在内存中的地址

//
int a[3] = {1,2,3};
printf("a = %#X\n",a);//a是一个指针常量,指向第一个元素
printf("*a = %d\n",*a);
printf("a[0] = %d\n",a[0]);

//输出
/*
a = 0X69FF04
*a = 1
a[0] = 1
*/

我们发现*a和a[0]实际上是一样的,都代表了数组中的第一个元素,当一个指针p指向一个变量时,*p就代表它指向的这个变量,其实a[0]就等价于 *(a + 0)

//
int a[3] = {1,2,3};
printf("a[0]的地址为%p\n",&a[0]);
printf("a[1]的地址为%p\n",&a[1]);
printf("a[2]的地址为%p\n",&a[2]);

//输出
/*
a[0]的地址为0069FF04
a[1]的地址为0069FF08
a[2]的地址为0069FF0C
*/

我们发现数组中每个元素的地址之间都相差4,这正是因为int变量占4个字节,而我们规定对于一个变量我们用它第一个字节在内存中的编号作为它的地址。也就是说,虽然对a[0]取地址输出的是0069FF04,但0069FF05 0069FF06 0069FF07也都是a[0]

现在就用到我们上面讲的地址偏移了,我们知道了数组中每个元素的地址之间相差4,那么我们就可以通过第一个元素的地址来找到第二个元素

//
int a[3] = {1,2,3};
printf("%p\n",a);
printf("%p\n",a+4);
printf("%p\n",a+1);
printf("%d\n",*(a+1));
/*
0069FF04
0069FF14
0069FF08
2
*/

a+4的结果和a差了16根本不是我们想要的a[1]的地址,而a+1刚好和a相差4,我们输出     a+1指向的变量,刚好也是第二个元素2,这是因为指针变量的加号运算符被重载了它的+1实际上加的是对应变量的长度,例如字符指针加一就是加一,而整形指针加一就是加四,所以无论是什么类型的数组,a[5]和*(a+5)都是完全等价的

总结:

1.(32位)所有类型的指针变量都占4个字节,我们用第一个字节的在内存中的编号来作为它的地址

2. 如果指针p指向i,那么*p完全等价于i

3. 数组在内存中是连续的的,每个元素都是相邻的,是一种连续的线性存储结构

4. a[i]完全等价于*(a + i)

加一道据说是去年的c++考试的题

//
using namespace std;
int x[4] = {10,20,30,40};
int *p = x;
cout << *++p << endl;//等价于++p; cout<<*p;
cout << *p++ << endl;//等价于cout<<*p; p++;
cout << ++*p << endl;//等价于int i = *p; ++i; cout<<i;
cout << (*p)++ << endl;
cout << *p << endl;

/*输出
20
20
31
31
32
*/

来简单看一下为什么

*++p   *和前自增优先级相同但是结合性是从左到右也就是先执行++在执行*                      *p++   后加加优先级高于*,他会先执行后自增结合的是p,但因为是自增,所以虽然它先执行,但是依然要等到*之后才加一                                                                             ++*p   优先级相同,从右向左,先* 再++  可以和第一个对比

有问题欢迎大家提问哦0。0 可以直接评论😂 也可以QQ🤣