学习c++已经快一年了,最近打算整理一下所学的知识,就当是系统地复习一遍,指针方面包括指针的简单介绍、使用指针常见的错误、指针与数组、指针与函数、指针数组和数组指针。
指针简单介绍
任何刚开始学习c语言的人如果被难住了,那一定是卡在指针这边了,其实指针并没有这么可怕,我这边就挑两个重点来讲了,如下:
1、指针是一种数据类型
2、间接赋值是指针存在的最大意义
第一点是什么意思呢,其实也没啥意思,比如int a=1;float b=1.0;char c='a',这边int是整型,float是浮点型,char是字符型,它们都可以称为是一种数据类型,所以我想说的是指针其实也只是一种数据类型,只不过是专门存放地址的数据类型而已,int a;int *p=&a;首先声明了一个变量a,然后声明了一个int*的变量p,将变量a的地址赋值给变量p,int*就是我想说的那个数据类型,这个数据类型你想怎么写都可以,不过至少要有一个*,int *p1;数据类型int*,存放整型变量的地址,int **p2,数据类型 int**,存放int*变量的地址,这其实就是二级指针了,*的数量是没有限制的,int **....* p100,100个*也是可以的,反正p100的值等于一个地址,这个地址是一个99级指针变量的地址。
第二点,间接赋值是指针存在的最大意义又是什么意思呢。请看下面的代码:
#include <stdio.h>
void main(int argc,char** argv)
{
int a=5;
int *p=&a;
*p=6;
printf("%d\n",a);
}
这个程序非常的简单,最后的结果是6,但是这并不能体现出指针存在的意义,我费尽周折改变了a的值,为什么不直接通过a=6的方式来改变呢?请再看下面的程序:
#include<stdio.h>
void swap1(int a,int b)
{
int c;
c=a;
a=b;
b=c;
}
void swap2(int*p1,int *p2)
{
int c;
if(p1&&p2)
{
c=*p1;
*p1=*p2;
*p2=c;
}
}
void main(int argc,char**argv)
{
int a=1;
int b=2;
swap1(a,b);
printf("a=%d,b=%d\n",a,b);
swap2(&a,&b);
printf("a=%d,b=%d\n",a,b);
}
这个程序想交换两个int类型变量的值,首先尝试swap1函数,最后打印的结果是"a=1,b=2",说明交换失败了,为什么呢?因为将a和b传给形参a和形参b,只是将a和b各自的一份拷贝给了形参a和形参b,你怎么使用这份拷贝,不关a和b的事。可是现在我就是想通过函数的形式来交换a和b,那该怎么做?很简单,把变量a和变量b的地址拷贝一份,传给函数,在函数里通过这两个地址访问main函数里的a和b,就像我把我家钥匙给你一把,虽然是拷贝的一把钥匙,但是你照样可以用这个钥匙来打开我家的门,不信的话可以尝试运行这个程序,第二次输出的就是"a=2,b=1",这就是指针能做到其它数据类型做不到的事。
指针类型的大小
在32位操作系统下,每种数据类型都有他对应的大小,因为每种数据类型存储数据的能力是不一样的,那么指针类型的大小是多少呢?只要通过printf("%d",sizeof(TYPE* ));就可以知道了,这里TYPE可以是各种类型,最后我们发现,无论是int*,还是float*,还是int**,打印出来都是4,也就是说指针类型是四个字节,为什么这些不同类型的指针都是四个字节呢,上面也提到了,指针变量就是存放地址的,所以这也就表示32位操作系统下,地址用四个字节表示,那为什么偏偏是四个字节,这和cpu寻址能力有关,因此,32位操作系统和64位操作系统的指针大小是不一样的,想要了解什么是cpu寻址能力的可以看王爽老师写的《汇编语言第2版》(可能有第3版了)的前几个章节,介绍的非常详细。
指针类型的作用
既然不管是什么类型的指针,在32位下都是4个字节,那么还要指针类型做什么,为何不都用void*呢?其实指针的类型主要影响对内存的解析方式,请看下面的代码:
#include<stdio.h>
#include<windows.h>
typedef struct Position
{
int x;
int y;
}Position, *LPosition;
void main(int argc, char**argv)
{
Position p1;
LPosition lp1 = &p1;
p1.x = 1;
p1.y= 2;
int a = *((int*)lp1);
int b = *(((int*)lp1) + 1);
printf("%d %d", a, b);
system("pause");
}
如图所示,如果以int*的方式去解析结构体变量的内存,那么一次只会取出四个字节,所以这个程序打印出的是p1.x和p1.y的值。
这篇博客暂时就总结这么多了,如果您发现有什么问题希望能够指出,感激不尽!