指针恐怕是C语言中最不容易掌握的一个概念了,但指针又是如此的重要,可以说不会指针,C语言就等于没学。
指针到底是一个什么东西呢?
- #include <stdio.h>
- int main()
- {
- struct mySt
- {
- int age;
- float money;
- double weight;
- float heigh;
- };
- char *pCh = NULL;
- char *pStr = "Hello Pointer";
- short *pShort = NULL;
- int *pInt = NULL;
- float *pFloat = NULL;
- double *pDouble = NULL;
- struct mySt* pStruct = NULL;
- printf("sizeof(pCh) = %d\n", sizeof(pCh));
- printf("sizeof(pStr) = %d\n", sizeof(pCh));
- printf("sizeof(pShort) = %d\n", sizeof(pShort));
- printf("sizeof(pInt) = %d\n", sizeof(pInt));
- printf("sizeof(pFloat) = %d\n", sizeof(pFloat));
- printf("sizeof(pDouble) = %d\n", sizeof(pDouble));
- printf("sizeof(pStruct) = %d\n", sizeof(pStruct));
- getchar();
- return 0;
- }
在编译目的为32位系统程序时,指针无论是指向基本数据类型,还是复杂数据类型,它所占的空间大小始终是4字节
再把编译目标设置为64位
同样指针无论是指向基本数据类型,还是复杂数据类型,它所占的空间大小始终是8字节。
指针所占空间大小的决定因素:
1. 最最根本的约定因素就是CPU。如果CPU是32位的,那么它所能够寻找的地址范围就在0 ~ 0xFFFFFFFF之间, 在这个区间的地址数据宽度都不会超过32位。指针变量的一个主要功能就是存放地址数据的,为了能够存放得下任意有效的地址,那么在32位CPU并且操作系统也是32位的情况下,指针所占内存宽度自然应该是4字节。
同理如果CPU是64的。它的寻址范围就是0~0xFFFFFFFFFFFFFFFF之间,在这个区间的地址数据宽度都不会超过64位,那么在64位操作系统下,并且生成的程序也是64的,在这程序当中,指针变量所占内存宽度自然应该是8字节。
2 如果编译器生成的目标程序是32位的,或者在64位CPU上运行的是32位操作系统。CPU虽然是64位的,但由于程序或操作系统寻址能力的限制,这时指针变量所占内存空间就是4字节32位。 因为64位是兼容32位的,所以32位程序和32位系统也能够正确运行
指针类型的声明方式:
- int *pInt;
- double *pDouble;
- Human *pHuman;
- int** p;
- Human**** h;
指针变量的赋值
- char *x
- short *y
- int* z
- x = (char*)1;
- y = (short*)2;
- z = (int*)3;
指针加, 指针减
- #include <stdio.h>
- int main()
- {
- char *pStr = NULL;
- int num[] = {1, 2, 3, 4, 5};
- int *pNum = num;
- pStr = "abcdefg";
- printf("%c\n", *(pStr++));
- printf("%c\n", *(pStr + 3));
- printf("%d\n", *(pNum++));
- printf("%d\n", *(pNum + 3));
- getchar();
- return 0;
- }
pNum用数组首地址初始化,所以此时pNum变量中存放的数值为0x0018ff44
pNum++ 这时指针自加显然已经不是简单的加1操作了。我们看到这时指针增加了4个字节,如果只增加一个字节,显然我们会得到错误
的结果。为了正确寻址数据,所以声明指针时要指定一种类型,知道了类型信息,那么编译器自然知道如何寻址和解释数据了。
pNum + 3 相当于0x0018ff48 + 3 * sizeof(int) 所以最张输出结果为5
结论: 指针是可以进行加减操作的。目的是方便数据寻址 通过以上观察我们可以得出这样一个公式
指针 +/- 数字 = 指针内容 +/- 数字*(sizeof(指针类型))
那么指针乘除显然没有任何意义。