目录
1,指针的理解
指针即为地址,通过对指针的应用,我们可以更加深层的运用代码。
以整形变量为例:
int a = 0;
a被创建后会被系统分配一个地址,此地址即为指针。
2,指针变量的创建
int a = 0;
int* p = &a;
p即为指针变量,*表示p的部分变量类型是指针,而int则表明指针指向的类型是一个整型,进而可以知道指针的变量类型取决于所指向的变量类型,如:
char b = 0;
char* p1 = &b;
3,指针的解引用
介绍完指针的创建后,我们要说说指针的使用,指针的使用体现在指针的解引用上,那具体操作是什么呢?
int a = 0;
int* p = &a;
对指针变量进行解引用:
p为指针变量,当我们要通过指针对变量进行修改时,解引用:
*p = 1;
此时变量a的内容由0改为了1,这就是对指针变量的解引用。
由此可得指针变量解引用后即为指针所指向的变量的元素本身。
4,指针的大小
指针的大小取决于操作系统,如果是32位操作系统,那么指针的大小为4个字节,64位系统,则是8个字节大小。
32位:4字节
64位:8字节
说到这里便有一些疑惑,既然指针本身就有固定的大小,那么指针变量的类型又有什么意义呢?
5,指针变量类型的意义
指针变量的类型肯定是有很重要的意义的,按照一般思维,我们会认为指针变量的大小应取决于其类型,因为int类型的变量总是占4个字节,char类型的变量总是占1个字节,这是我们所知道的。但其实在某种程度上,也可以说指针变大小与其类型有关。
指针的大小的确是固定的,但在对指针进行操作时,是按指针变量类型的大小来进行操作的:
int a = 1000;
char* p1 = (char*)&a;
*p1=0;
printf("%d\n", a );
程序输出后的结果不是1000,而是768,这是因为在内存中,a原本占4个字节,用char*的类型取地址后,再进行解引用,此时再对*p1进行修改时是按char类型的大小来的,因此只修改一个字节的数字:
修改前: 修改后:
(内存中显示的是16进制的形式,从右至左读,16进制 300 转10进制 768 )
6,指针的运算
指针+num;
指针-num;
指针-指针;
指针的运算同样和指针变量的类型相关:
int arr[ ]={0,1,2,3,4,5,6};
int* p=arr;
printf("%d",*(p+1));
指针可以直接进行加减,加减变化的字节取决于指针变量的类型,“int*”加一后跳过4个字节,如果是“char*”就跳过1个字节,减法同理。
当指针减指针是得出来的是两指针相差的元素个数,单位元素个数的字节大小同样取决于指针变量类型。
7,数组指针
我们知道数组名只在两种情况下表示数组的全部内容:
1),sizeof(数组名);
2),&数组名;
其余情况均取数组首元素的地址。
那么数组指针要想指向数组的全部内容,它的赋值应是 &数组名。
变量的创建格式为(以整型为例):
int arr[5] = {0,1,2,3,4};
int (*p)[5] = &arr;
----------------------------------------------------------------------------------------
需要注意的是,数组在函数传参时本质上也是在传指针,但不是整个数组指针,而是数组首元素指针即首元素地址。
8,字符指针
字符指针变量相信大家很容易能写出来了
char n = "w";
char* p = &n;
那如果是字符串呢?
1)const char* n1 = "hello world";
2)char* n2[] = "hello world";
(需要注意的是1)为常量字符串,因此char*前要加const)
但无论是数组中的字符串还是常量字符串,指针指向的都是首个字符的地址。
9,函数指针
函数指针变量的创建格式为(以返回整型为例):
int (*p)(int ,int)
(*p)前面为函数的返回类型,后面为函数的参数类型,p为指针变量。