指针是C语言重点之一,使用非常广泛,恰当的使用会使程序看起来更简单,当然,使用不恰当的话会使指针指错了地方。
指针:一种保存变量地址的变量。
1.声明形式化一般为 type(指针类型) *name;
2.在32位平台上地址用4个字节空间来存储,在64位平台上地址用8个字节空间来存储;
一级指针:即指针,存放内存地址。
二级指针:存放指针变量地址的指针。
#include <stdio.h>
int main()
{
int a=30;//定义了一个整型变量a
int *p=NULL;//指针变量的声明,NULL 指针是一个定义在标准库中的值为零的常量
p=&a;//一级指针变量p存放了整型变量a的地址
int **ptr=&p;//二级指针变量ptr存放了一级指针变量p的地址
return 0;
}
指针类型
指针变量和普通变量一样都是具有类型的,指针变量的类型是type * 的格式。
int *p=NULL; //int * 类型指针为了存放int类型变量的地址
char *str=NULL; //char * 类型指针为了存放char类型变量的地址
float *tmp=NULL; //float * 类型指针为了存放float类型变量的地址
double *ret=NULL; //double * 类型指针为了存放double类型变量的地址
……
指针类型的确定:把指针声明里的名字去掉,剩下的部分就是这个指针的类型。
int *p;//指针的类型是int *
float **f;//指针的类型是float **
int (*ptr)[3];//指针的类型是int (*)[3]
指针所指向的类型:把指针声明的名字和名字左边的 * 去掉,剩下的部分就是指针所指向的类型.
int *p;//指针所指向的类型是int
float **f;//指针所指向的类型是float *
int (*ptr)[3];//指针所指向的类型是int ()[3]
指针运算
1.指针的自增,自减运算
对指针进行自增,自减运算时,即值增减数据类型字节数。
#include <stdio.h>
#define MAX 4
int main()
{
int arr[MAX]={2,4,6,8};
int *ptr=NULL;
int i=0;
ptr=arr;
for(i=0;i<MAX;i++)
{
printf("arr[%d]=%p\n",i,ptr);
ptr++;
}
return 0;
}
2.指针减指针运算
指针减指针运算前提是两个指针属同一份空间,结果是两个指针之间元素的个数
#include <stdio.h>
#include <assert.h>
int my_strlen(const char *str)
{
const char *start=str;
assert(str);
while(*str!='\0')
{
str++;
}
return str-start;
}
int main()
{
const char *str="abcdef";
int ret=my_strlen(str);
printf("%d ",ret);
return 0;
}
3.指针解引用
可以通过解引用操作符*来获取指针指向地址的内容.
指针的类型决定了对指针解引用时能操作几个字节。
int *的指针解引用能访问4个字节;
char *的指针解引用能访问1个字节。
#include <stdio.h>
int main()
{
int p=10;
int *pa=&p;
*pa=0;
char *pc=&p;
*pc=0;
return 0;
}
例:用指针形式进行冒泡排序
#include <stdio.h>
void Sort(int *arr, int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (*(arr + j) < *(arr + j + 1))
{
int ret = *(arr + j);//对指针解引用得到了数组中元素的值
*(arr + j) = *(arr + j + 1);
*(arr + j + 1) = ret;
}
}
}
}
int main()
{
int arr[] = { 1, 3, 5, 7, 9, 0, 8, 6, 4, 2 };
int size = sizeof(arr) / sizeof(arr[0]);//sizeof求数组的长度
int i = 0;
Sort(arr, size);
for (i = 0; i < size ; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
4.指针加减整数
不同类型的指针加减整数,向前或向后移动的字节不同。
#include <stdio.h>
int main()
{
int tmp=10;
int *pa=&tmp;
char *pc=(char *)&tmp;
printf("%x\n",pa);
printf("%x\n",pa+1);
printf("%x\n",pc);
printf("%x\n",pc+1);
return 0;
}
const修饰指针
1.const 修饰一级指针
int main()
{
int num=15;
const int *p=#//不能改变指针变量p所指向的内容
int * const p=#//不能改变指针变量p所指向的变量,但其内容可变
2.const 修饰二级指针
int main()
{
int num=16;
int *p=#
int **ptr=&p;
int const **ptr=&p;//不能通过ptr来改变p所指向地址存的变量所指向的空间内容(不能通过ptr来改变num)
int ** const ptr=&p;//ptr不能改变指向
int * const *ptr=&p;//不能通过ptr来改变其所指向的内容
}