数组指针,指向数组的指针,本身是一个指针。
int a[3];
int (*p)[3]=&a; //指向的是数组a的地址,整个数组的地址,而不是数组的一个元素的地址;
指针数组:本身是一个数组,数组中存储的元素为指针。
int* a[3];存储三个int* 的指针
指针函数--本身是一个函数,返回值是一个指针变量 int *fun(int);
函数指针--本身是一个指针,指针指向的是一个函数 int (*fun)(int);
int add(int num){
num++;
return num;
}
int (*fun)(int)=add; //函数指针就是函数的入口地址
int (*fun)(int)=NULL; fun=add; int a=fun(100);
通过函数指针来调用函数 fun(100); 与add(100)相同。
函数指针智能化调用封装好的函数。
练习,1.计算一个二维数组的和(用指针数组)
2.用计算器实现加减乘除:
#include<stdio.h>
int main(){
int array[4][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
int* p[4]={array[0],array[1],array[2],array[3]};
int sum=0;
for (int i=0; i<4; i++) {
for (int m=0; m<4;m++) {
sum+=(*(p[i]+m));
}
}
printf("%d\n",sum);
printf("%d\n",*(p[0]+1));
return 0;
}
#include<stdio.h>
int add(int a,int b){
int asum=a+b;
printf("两个数相加的和为:%d\n",asum);
return 0;
}
int sub(int a,int b){
int ssum=a+b;
printf("两个数相减的差为:%d\n",ssum);
return 0;
}
int cheng(int a,int b){
int csum=a*b;
printf("两个数的乘积为:%d\n",csum);
return 0;
}
int chu(int a,int b){
int chsum=a/b;
printf("两个数相除结果为:%d\n",chsum);
return 0;
}
int main(){
int inputa,inputb;
printf("请输入第一个数:");
scanf("%d",&inputa);
printf("请输入一个运算符号:");
char a;
scanf("%s",&a);
printf("请输入第二个数:");
scanf("%d",&inputb);
//先定义一个函数指针,函数指针本身是一个指针。
int (*fun)(int,int)=NULL;
switch (a) {
case '+':
fun=add;
fun(inputa,inputb);
break;
case '-':
fun=sub;
fun(inputa,inputb);
case '*':
fun=cheng;
fun(inputa,inputb);
case '/':
fun=chu;
fun(inputa,inputb);
default:
break;
}
return 0;
}
回调:在函数内部调用外面的函数,函数指针作为函数参数(回调函数);
函数指针数组:本身是一数组,数组中存储的是指针,指针指向的是函数类型。int(*a[4](int,int))={add,sub,mul,devl};
数组作为函数的参数---相当于指针
int a[5];
int array_sum(int *a,int len){
}
array_sum(a,5);
特点:数组作为函数参数,传入后在函数中就是指针,指针大小(32系统中4字节,64位系统8字节)
指针常量
void*p;void类型---只能定义指针变量,不能定义普通变量 void a(错误,不能定义普通变量)
void 指针变量可以强制转换为任意类型指针。void类型不能解引用,就是不能用*来取值
const int *p; 指向常量的指针(不能通过指针p来改变数据)(限制了指针的权限通过加一个const)
int *const p; 常指针(定义的时候必须初始化,所指向的地址不能改变)int a=10; int *const p=&a; int b=30;p=&b;(错误)
const int *const p=&a; 指向常量的常指针
结构体:
基本数据类型 数组,函数,结构体
struct 结构体名{
结构体成员
};
结构体的大小要看结构体内成员的数据类型,4字节就4字节对齐,8字节就8字节对齐,遵循字节对齐。64位系统(2,4,8对齐),在结构体中选择最大数据类型字节对齐。
加上#pragma pack(4), 里面的数就是自己设定的多少个字节对齐,一般来说不要这样做,会增大操作系统的负担,因为要重新分配空间。
结构体特点:1.结构体空间连续 2.结构体在没有定义对象之前是不占用内存空间。3.结构体存储遵循字节对齐。
定义结构体对象:struct Student 对象名; 定义了结构体对象就分配来空间,大小为:sizeof(struct Student) 对象名. 结构体成员(.符号-对象取成员)。
练习:设计一个学生结构体并定义一个list结构对象,从键盘上输入数据初始化list对象并输出list信息。
#include<stdio.h>
int main(){
struct Student {
char name[30];
int age;
float height;
char qq[13];
char tel[12];
char addr[120];
};
struct Student list;
char name[30];
printf("请输入学生的信息:\n");
printf("姓名:");
scanf("%s",list.name);
printf("年龄:");
scanf("%d",&list.age);
printf("身高:");
scanf("%f",&list.height);
printf("qq号:");
scanf("%s",list.qq);
printf("电话号码:");
scanf("%s",list.tel);
printf("地址:");
scanf("%s",list.addr);
printf("%s\n%d\n%f\n%s\n%s\n%s\n",list.name,list.age,list.height,list.qq,list.tel,list.addr);
return 0;
}