对一个非指针变量例如int a,可以用&(取地址符)来取出a的地址,将这个地址存入一个指针变量中
int a = 10;
int* pa = &a;
这个指针变量,同理,整型存储整数,而指针类型存储指针(地址)
int a = 0;
int *pa = &a;
char b = 'A';
char *pb = &b;
float c = 0.3;
float *pc = &c;
总之就是指向什么数据类型(例如指向int)就用什么样的指针类型(指针类型为int*),即格式为:
指针指向的变量类型* 指针名称
#include
int main()
{
int n = 0x11223344;//十六进制数字
char* pc = (char*)&n;
int *pi = &n;
*pc = 0; //观察内存的变化
*pi = 0; //观察内存的变化
return 0;
}
#include
//演示实例
int main()
{
int n = 10;
//0000 0000|0000 0000|0000 0000|0000 1010
char *pc = (char*)&n;//将int*类型的指针强制转化为char*类型
int *pi = &n;//指向类型和指针类型一一对应
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;
}
可以看到指针类型决定了指针向前和向后的步长有多大,注意,系统提供的地址在不同机器有可能不一样
#include
int main()
{
char arr[] = "abcdef";
int a = arr[5] - arr[0];
printf("%d", a);//得到两个指针之间元素的个数
return 0;
}
#include
int main()
{
int arr[10] = { 1,1,2,4,3 };
if (&arr[3] > &arr[0])
{
printf("(&arr[3])是高地址\n");
}
return 0;
}
另外标准规定,允许指向数组元素的指针与与指向数组最后一个元素后面的那个内存的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
野指针就是指针指向的位置是不明确的不可知的(随机的、不正确的、没有明确限制的)
#include
int main()
{
char *a;//这里只是声明了指针变量,没有明确指针指向的数据具体是什么,只知道该数据是int类型
scanf("%s", a);//scanf访问了一个野指针
printf("%s", a);
return 0;
}
#include
int main()
{
int arr[4] = {1, 2, 4, 0};
for(int i = 0; i < 10; i++)//这里的10不应该超过4,要改成比4小的数字
{
*(arr++) = i;//数组越界访问了,其结果是未知的,程序也有可能异常中止
)
return 0;
}
指针指向的空间释放主要在动态内存开辟的时候才会出现,有关动态内存的知识之后再说
实际上指针和数组的关系十分密切
#include
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", arr + 1);
printf("%p\n", &arr[1]);
return 0;
}//打印的结果是一样的,因此我们可以得出一个结论:数组名就是首元素地址
还可以写出如下的代码
#include
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int* p = arr; //指针存放数组首元素的地址
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz; i++)
{
printf("\"&arr[%d] = %p\" 和 \"p+%d = %p\"\n", i, &arr[i], i, p + i);
}
printf("\n");
for (int i = 0; i < sz; i++)
{
printf("\"&arr[%d] = %d\" 和 \"p+%d = %d\"\n", i, arr[i], i, *(p + i));
}
return 0;
}
是变量就需要开拓一块内存来使用,每块内存都需要一个地址来维护,因此,只要是变量就会有地址,而指针变量也是一种变量,所以指针变量也有地址,那么一个一级指针变量的地址应该存放在一个什么样的指针类型变量里呢?答案就是二级指针
int a = 10;
int *pa = &a;
int* *ppa = &pa;
理顺一下逻辑:ppa存放的是“变量pa的地址”,pa存放的是“变量a的地址”
顾名思义,是一个数组,每个数组元素是“一个指针变量”
#include
int main()
{
int a = 1;
int b = 9;
int c = 4;
int d = 6;
int* arr[4] = { &a, &b, &c, &d };
for (int i = 0; i < 4; i++)
{
printf("%p\n", arr[i]);
}
return 0;
}
顾名思义,是一个指针,这个指针存放的是“整个数组的地址”
#include
int main()
{
int arr[3] = { 6, 2, 3 };//实际上,任何一个变量,只要删去变量名,剩下的就是变量的类型,因此这个数组的类型就是int[3]
int(*p1)[3] = &arr;//&arr是取出整个数组的地址
printf("%p\n%p\n", p1, p1 + 1);
int(*p2)[3] = (p1 + 1);
printf("%zd", (p2) - (p1));//得到int()[3]元素有1个
return 0;
}