指针数组:
本质上是一个数组,只不过这个数组里面每一个元素都是指针
一般形式:
<数据类型> *<数组名>[下标];
下标代表数组有多少个元素
int a = 1, b = 2, c = 3, d = 4, e = 5;
int *arr[5] = {&a, &b, &c, &d, &e};
指针数组和一维数组的联系:
int a[5] = {1,2,3,4,5};
int *arr[5] = {a, a+1, a+2, a+3, a+4};
char a[] = "hello", b[] = "world", c[] = "welcome";
char *str[3] = {a, b, c};
puts(str[0])
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void ptr_arr(int a[],int n)
{
for(int i=1;i<n;i++)
{
printf("%d ",a[i]);
}
puts("");
}
int main(int argc, char *argv[])
{
int a[]={1,2,23,5,6,7};
int n=sizeof(a)/sizeof(int);
ptr_arr(a,n);
return 0;
}
指针数组和二维数组的联系:
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int *arr[3] = {a[0], a[1], a[2]};
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
printf("%d ", *(arr[i]+j)); //printf("%d ", arr[i][j])); //printf("%d ", *(*(arr+i)+j));
}
puts("");
}
数组指针:
本质上是一个指针,只不过这个指针指向的是整个数组
一般形式:
<数据类型> (*<数组指针变量名>)[下标];
下标代表要指向的数组的元素个数
int a[3] = {1,2,3}, b[4] = {1,2,3,4};
int (*p)[3] = &a; //p == &a --> *p == a
for(int i = 0; i < 3; i++){
printf("%d ", (*p)[i]); //(*p)[i] == *(*p+i) == p[0][i]
}
数组指针和二维数组的关系:
二维数组数组名是行地址也是行指针
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
//a的类型:int (*)[4]
int (*p)[4] = a; //a == &&a[0][0]
for(int i = 0; i < 3; i++){
for(int j = 0; j < 4; j++){
printf("%d ", *(*(p+i)+j)); // *(*(p+i)+j) == *(p[i]+j) == p[i][j] == (*(p+i))[j]
}
puts("");
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int(*p)[4]=a;
int i,j;
int max=a[0][0];
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
printf("%d ",*(*(p+i)+j));
if(max<a[i][j])
max=*(*(p+i)+j);
}
}
puts("");
printf("max=%d\n",max);
return 0;
}
二级指针和二维数组没有直接关系
void *:
任意类型的指针
在使用时,需要强转为具体类型的指针
const int a = 10;
int *p = (int *)&a;
const int *p
int *const p
const int *const p
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char a=65;
short b=123;
int c=45;
void *p;
p=&a;
printf("%c\n",*(char *)p);
return 0;
}
函数:
具有特定功能的代码模块
一般形式:
<数据类型> <函数名>(形参列表)
{
函数体;
return;
}
int add(int a, int b)
{
return a+b;
}
int sum = add(1,2);
函数的值传递:
直接赋值操作
函数的地址传递:
是把需要修改的实参的地址传递进去
void ptr_arr(int a[], int n)
{
//int len = sizeof(a)/sizeof(a[0]); //err
//a是指针
for(int i = 0; i < n; i++){
printf("%d ", a[i]);
}
puts("");
}
int get_max(int c, int (*a)[c], int b);
int get_max(int m, int n, int a[][n]);
指针函数:
本质上是一个函数,只不过函数返回的是一个地址
一般形式:
<数据类型> *<函数名>(形参列表)
{
函数体;
return;
}
注意:
不能返回局部变量的地址,因为函数调用结束,局部变量全部被销毁
函数指针:
本质上是一个指针,只不过该指针指向一个函数
一般形式:
<数据类型> (*<函数指针名>)(形参列表);
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int add(int a,int b)
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int main(int argc, char *argv[])
{
// int (*p)(int, int);
typedef int (*Pfun)(int,int); //给int(*p)(int,iny)取别名
Pfun p;
p = add; //让指针指向函数
printf("%d \n",p(1,2));
printf("%d \n",(*p)(1,2));
p = sub;
printf("%d \n",p(1,2));
printf("%d \n",(*p)(1,2));
return 0;
}