1、指针的运算
指针+整数 = 指针
指针-整数 = 指针 和加法的规则一样。
结论:实际增加\减少 = 整数 +- 指针所指向类型所占内存大小
int a = 10,b = 20,c = 30;
printf("a=%d,b=%d,c=%d\n",a,b,c);
int *pa = &a,*pb = &b,*pc = &c;
printf("pa=%d,pb=%d,pc=%d\n",pa,pb,pc);
int *pd = pa +10;
printf("pd = %d\n",pd);
double d = 45.6;
double *pdouble = &d;
printf("pdouble = %d\n",pdouble);
printf("pdouble + 5 = %d\n",pdouble + 5);
char ch = 'A';
char *pch = &ch;
printf("pd = %d\n",pch);
printf("pd = %d\n",pch + 5);
printf("%d\n",pa - pb );
指针的运算
在一段连续的内存空间,数组,动态开辟的内存中使用
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("arr = %d\n",arr);
printf("arr = %d\n",&arr[0]);
printf("arr = %d\n",&arr[1]);
//arr 是常量
//arr 的类型 指向int型的指针
int* parr = arr;
printf("arr = %d\n",arr+1);
printf("arr = %d\n",arr+2);
printf("arr = %d\n",arr+10);//能打印 但是越界了
指针和一维数组的关系:
//推导
arr + 0 = &arr[0]
arr + 1 = &arr[1]
arr + 2 = &arr[2]
...
arr + 3 = &arr[3]
//继续推导
*(arr + 0) = arr[0]
*(arr + 1) = arr[1]
*(arr + 2) = arr[2]
...
*(arr + 3) = arr[3]
注意:
,<这两个判断指针的大小,需要在一段连续的内存空间比较才有意义。
== != 这两个可以随意比较。
指针和二维数组的关系:
1、arr表示 什么? 首地址型是什么? 不是指向int型的指针,是一个指向一维数组的指针
2、可以把二维数组看做成一维数组,只不过这个一维数组中每个元素有5个元素
int i = 0;
int j = 0;
int arr[4][5]=
{
{1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20}
};
for(i = 0;i<4;i++)
{
for(j = 0;j<5;j++)
{
printf("a[%d][%d] = %d ",i,j,arr[i][j]);
//另一种访问方式:
printf("a[%d][%d] = %d ",i,j,*(*(arr+i) + j));
}
// printf("\n");
}
指针数组:是一个数组,数组里面存储的都是指针。
int * arr[4] = {&a,&b,&c,null };
数组指针:是一个指针
typedef int(*PARR)[5];//是一种新的类型 ,数组指针类型
arr; //数组指针 指向一个数组
int (*parr)[5] = arr;//现在就定义了数组指针
PARR parr2 = arr;
地址偏移了多少?
printf("%d\n",arr + 0);//偏移的字节数 = 类型*大小
printf("%d\n",arr + 1);
printf("%d\n",arr + 2);
printf("%d\n",arr + 3);
printf("\n");
printf("%d\n",*(arr + 0));//得到整个数组,数组名=》arr2[0]
printf("%d\n",*(arr + 1));
printf("%d\n",*(arr + 2));
printf("%d\n",*(arr + 3));
推导:
*(arr + 0) = 》arr[0]
*(arr + 1) = 》arr[1]
*(arr + 2) = 》arr[2]
*(arr + 3) = 》arr[3]
arr + 0; //类型是指向整个一维数组的指针
arr[0]; //类型是指向整型的指针
*(*(arr+0) + 0) =》 arr[0] + 0;
*(arr+0) + 2 =》&arr[0][2]=》 arr[0] + 2;
*(*(arr+0) + 2) =》3//得到数字3
printf("%d\n",*(*(arr+1) + 2));
推导
*(*(arr+0)+0) => arr[0][0]
*(*(arr+0)+1) => arr[0][1]
*(*(arr+0)+2) => arr[0][2]
*(*(arr+0)+3) => arr[0][3]
三维数组:
int arr[2][3][4] = {0,1,2,3};
int (*parr)[3][4] = arr;
指针和字符串的关系,这个指针的类型是 : char *型
//字符串的首地址,指针
printf("%d\n","hello,world");
char *str = "hello world";
printf("%s\n",str);
*"hello,world";
printf("hello,world = %c\n",*"hello,world"); //得到的是h
printf("hello,world = %c\n",*("hello,world"+1)); //打印出e
数组下标访问和数组的间接访问
printf("hello,world [0]= %c\n","hello,world"[0]);
数组指针:是一个指针,指向数组的指针
区别 占用空间不一样。
char str[4][10] = {"hello world","china","123456","yellow"};
char *strarr[4] = {"hello world","china","123456","yellow"};
for(i = 0;i<4;i++)
{
printf("%s\n",strarr[i]);
}
交换两个变量的数值
传值和传址不同,传值都是传递的一种拷贝,不管传值还是传地址 都是传递的是一种拷贝。
void swap(int *pa,int *pb)
{
int temp = *pa;
*pa = *pb;
*pb = temp;
}
void display(char* str)
{
printf("%s\n",str);
}
传递一个数组
数组作为函数参数传递的时候,传递的是首地址,而不是整个数组了,已经变成了地址而不是数组了。
//方式1
void printArr(int arr[],int length);
//方式2
void printArr(int *arr,int length)
{
for(int i; i<length;i++)
{
//printf("%d, ",arr[i]);
printf("%d, ",*(arr+i));
}
printf("\n");
}
//主函数
printArr(arr,sizeof(arr)/sizeof(arr[0]));
二维数组作为函数参数传递。
void printArr2(int (*arr)[5],int x,int y)
{
for(int i = 0; i<x;i++){
for(int j = 0; j<y;j++)
{
printf("%d, ",arr[i][j]);
}
printf("\n");
}
}
//二维数组作为函数参数进行传递
int arr2[4][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
printArr2(arr2,4,5);
void showdouble(double *d)
{
printf("浮点数 :%f\n",*d);
}
double d = 456.678;
showdouble(&d);
指针作为函数的返回值
注意:返回的地址必须是可用的,就是没有释放的。
int* test()
{
int a= 10,b=20,c=10;
c = a + b;
return &c;
}
int *p = test();
*p = 45; //后续不可以使用
printf("p=%d\n",*p);
//没问题的
int* test1(int *c)
{
*c = 1000;
return c;
}
int *pa = test1(&a);
printf("a= %d\n",a);
数组不能作为函数参数返回。
函数指针:
类型是什么?
类型是指向函数的指针。
void show()
{
printf("你好");
}
printf("show = %d\n",show); //打印函数名,函数指针
void(*pShow)() = show;//pShow是一个函数指针
(*pShow)();
//另一种写法
pShow();
指向函数的指针
typedef void (*PSWAP)(int *,int *) ;//定义一种新类型
void (*pswap)(int *pa,int *pb) = swap;//指向函数的指针
pswap(&a,&b);
PSWAP pswap = swap; //起别名
printf("a=%d,b=%d,c=%d\n",a,b,c);