1,指针变量
int *p=&a
这里的*与p结合,说明p是一个指针变量。
int代表p指向的对象是int类型的。
2,指针变量的大小
在64位环境下,指针变量的大小都为4个字节。
在32位环境下,指针变量的大小都为8个字节。
指针变量大小的类型决定了指针在解引用操作时访问几个字节。
3,对指针的理解
a=10;
int *p=&a;
1)p中可以存放一个地址
2)*p=a=10;
3)p本身具有一个地址
4,const修饰指针变量
1)int * const p
不能修改p,可以修改p指向的内容。
2)int const *p
不能修改p指向的内容,可以修改p本身。
5,指针的使用
在传参的时候,我们要是想改变实参的内容,这个时候我们就要使用到指针了。
因为在传参的时候,形参是实参的一份临时拷贝,形参的修改不会影响到实参,所以这个时候我们要想改变实参,就应该传递实参的地址,此时对形参的改变也就是对实参的改变了。
6,二级指针
二级指针是用来储存一级指针的地址的指针。
a=10;
int *p=&a;
int **pp=&p;
*pp=p=&a;
*p=a;
**pp=*p=a;
此时对于pp解引用一次得到的就是p中存储的内容,再对p解引用找到的就是a。
如果对于pp解引用两次,找到的便是a。
7,指针数组(int *arr[5])
在数组中,arr[i]=*(arr+i)=*(i+arr)=i[arr]
本质上是一个用来存放指针的数组,也可以用它来模拟应该二维数组。
#include<stdio.h>
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* parr[3] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
8,字符指针变量
char* str="hello";
这里的hello被称为常量字符串,不能被修改。
此时是把字符串"hello"的首字母的地址放入了str中。
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
在这道题目中,str1和str2作为字符数组开辟了两个空间,而str3与str4作为字符指针变量中存储的为常量字符串,只开辟一份空间,所以str3与str4应该是相同的,而str1与str2不同。
9,数组指针变量
数组指针变量本质上是一个指针,存放的内容是数组的地址,指向的内容是数组。
int (*p)[10]=&arr,这里的*与p优先结合,p为一个指针变量,然后指向的内容为int类型的数组。
void test(int(*p)[5], int r, int c)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
printf("%d ", (*(*p + i) + j));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
test(arr, 3, 5);
return 0;
}
这里的二维数组传参是传递的为第一行一维数组的地址。
10,函数指针变量
函数也是拥有着它自己的地址的,将函数的地址存储起来的指针变量便叫做函数指针变量
int (*p)(int,int)
*p表示p为一个指针变量,前面的int表示其返回值的类型,后面的(int,int)表示参数类型。
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*p)(int, int) = add;
printf("%d\n", p(2, 3));
printf("%d", (*p)(3, 3));
return 0;
}
函数名就是函数的地址,所以这里不用写&arr也可以
在这组代码中p中储存的是add函数的地址,在调用函数是,不需要对p进行解引用也可以进行。
11,函数指针数组
本质上是一个存储函数指针的数组,即将函数的地址都存储与一个数组中。
int (*p[10])(int,int)
int (*)(int,int)
p[10]是一个数组,它的类型是int (*)(int,int),即为函数指针。
12,qsort函数
int cmp_int(void* p1,void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
int main()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
qsort(arr, 10, sizeof(int), cmp_int);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}