指针进阶(一)
指针的运算
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]);
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));
}
}
指针数组:是一个数组,数组里面存储的都是指针。 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));
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
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");
printf("hello,world = %c\n",*("hello,world"+1));
数组下标访问和数组的间接访问
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);
}
传递一个数组 数组作为函数参数传递的时候,传递的是首地址,而不是整个数组了,已经变成了地址而不是数组了。
void printArr(int arr[],int length);
void printArr(int *arr,int length)
{
for(int i; i<length;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();
指向函数的指针
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);
|