1.指针和指针类型
我们都知道变量有不同的类型,那指针有类型吗?
可以肯定地说,有。
type* 类型的指针表示该指针指向一个type类型的变量。
有了指针类型,就确定了指针的运算规律。
指针+-整数
int main()
{
int n = 10;
char* pc = (char*)&n;
int* pi = &n;
printf("%p\n",&n);
printf("%p\n",pc);
printf("%p\n",pc+1);
printf("%p\n",pi);
printf("%p\n",pi+1);
return 0;
}
输出结果为:
总结:指针的类型决定了指针向前或向后走一步有多大。
指针-指针
指针相减这种操作时允许的,我们来看一个实例:
int my_strlen(char* s)
{
char* p = s;
while (*p != '\0')
{
p++;
}
return p-s;
}
调试结果为:
显然,指针相减与指针的类型是有关的,但并不代表类型决定着指针的大小。
指针的解引用
int main()
{
int n = 0x11223344;
char *pc = (char*)&n;
int *pi = &n;
*pc = 0x55;
*pi = 0;
return 0;
}
重点观察一下内存变化:
不难看出,指针的类型决定了对指针解引用时可操作的字节大小。
2.二级指针
存放指针变量的地址的变量就是二级指针,因此,多级指针的概念与之类似。
在认识了二级指针之后,我们可以尝试一下指针和数组的相关运算,有兴趣可以点击博文让初学者自闭的代码。
3.几个关于指针和数组的概念
指针数组
指针数组是一个数组,是一个存放指针的数组。
数组指针
数组指针是一个指针,他有能力指向一个数组。
让我们了解一个简单的数组指针的定义:int (*p)[10];
//这里,p先和*结合,说明p是一个指针,指向一个大小为10个元素的整型数组。所以,p是一个指针,指向一个数组,叫数组指针。
//[]优先级高于*,所以要加上括号,以保证p先和*结合。
函数指针
函数指针仍然是一个指针,它指向一个函数的位置。
函数指针数组
不难理解,这是一个数组,来存放函数的指针。
一个简单的定义:int (*parr[10])();
//这里,arr是一个数组,里面的元素是int (*) ()类型的函数指针
函数指针的数组的指针
函数指针的数组的指针是一个指针,指针指向的是一个数组,数组的元素是函数指针。
4.练习题
int main()
{
int a[5] = { 1,2,3,4,5 };
int *ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1);
return 0;
}
//程序的结果是什么
struct Test
{
int num;
char* pcname;
short sDate;
char cha[2];
short sBa[4];
}*p;
假设p的值为0x100000,以下表达式的值分别是多少?
p + 0x1 = ?
(unsigned long)p + 0x1 = ?
(unsigned int*)p + 0x1 = ?
int main()
{
int a[4] = { 1,2,3,4 };
int *ptr1 = (int*)(&a + 1);
int *ptr2 = (int*)((int)a + 1);
printf("%x,%x",ptr1[-1],*ptr2 );
return 0;
}
int main(int argc,char * argv[])
{
int a[3][2] = { (0,1),(2,3),(4,5) };
int *p;
p = a[0];
printf("%d", p[0]);
return 0;
}
//输出结果是什么?