一、指针
为了正确的访问内存单元,每个内存单元都有一个编号。内存单元的编号称作地址
访问方式:
直接访问:直接访问内存单元中的内容 例 a = 20;
间接访问:通过访问内存单元的编号(地址)以及数据多占字节数访问内存中的数据
(间接访问随处可见,指针就是间接访问的常用方式)
1.指针定义:存放内存地址的变量
int *p = NULL;//初始值: NULL 恒等于 0
//指针所占字节数只与 操作系统位数 有关
①指针类型转换符(占位符): %p
printf("p = %p\n",p);
②取地址符:&
int a = 3;
int *p = &a;
printf("&a = %p\n",&a);
printf("p = %p\n",p);
③取值运算符:*
int a = 3, b = 5;
int *p = &a;
printf("%d\n", *p);
p = &b;
*p = 100;
printf("%d\n", b);
2.指针的算术运算:只有加、 减运算
int a = 3;
int * p = &a;
p++; //向⾼高位移动四个字节 !
p--; //向低位移动四个字节!
//注意:指针类型决定移动几个字节
3.指针的重指向:指针变量的赋值意味着重指向
注意:p:在指针定义时,只起修饰作用
在指针变量取值时,*表示取p地址内存里的内容
4.数组的内存地址
数组:用连续内存空间存储数据的构造类型
注意:数组名 即 整个数组的 首地址
例:int arr[3] = {1,3,7};
arr 恒等于 &arr[0]
5.指针与数组
指针可以当数组名用
指针和数组的区别:①所占空间不同,指针只与操作系统位数有关,数组与元素个数和类型有关
②数组名是常量地址,不可以重指向
6.指针与字符串
同数组一样,字符数组名及即数组指针首地址
7.指针数组
定义:存放指针的数组
char *strings[3] = { "iOS", "Android", "Win10"};
8.指针与函数
指针作为参数
void swap(int *a,int *b);
9.函数调用时,,实参只是拷贝形参的值,形参改变并不会改变实参的值
二、指针高级
10.结构体指针
定义:
指向结构体变量的指针
typedef struct student Stu;
Stu stu1 = {0};
Stu * p = &stu1;
访问:
11.结构体数组
与指针的关系
结构体数组名是一个结构体指针常量
结构体指针为函数参数
函数声明:
void printStudents(
Stu* pstu,
int count
);
函数操作结构体数组时,需要传入首地址和元素个数
12.预编译指令
普通宏:
宏定义:(预编译进行替换)例:#define PI 3.1415
命名规则:纯大写 或者 k+驼峰式
带参数的宏:
#define MULL(A,B) ((A)*(B)) //加括号是为了防止手操作符优先级的影响
条件编译:
作用:按不同条件,编译不同的代码
形式一:
#ifdef 标示符 代码段1 #else 代码段2 #endif
//如果 标示符 被#define 过,编译器编译代码段1,否则编译代码段2
形式二:
#ifndef 标示符 代码段1 #else 代码段2 #endif
//如果 标示符 未被 #define过 编译器编译代码段1,否则编译代码段2
形式三:
#if 常量表达式 代码段1 #else 代码段2 #endif
//如果 常量表达式 结果非0 编译器编译代码段1,否则编译代码段2
三、函数指针
1.定义:
int maxValue(int a,int b)
{
return a > b ? a : b;
}//函数名同数组名一样 是地址
指针可当函数用:
int *p = maxValue;
int m = p(3,5);
2、回调函数
函数指针做参数:
int value = getValue(3,5,maxValue);//getValue执行的过程中再调用(回调)maxValue
3.动态排序
排序类:if条件 (声明 BOOL类型)
#import <Foundation/Foundation.h>
typedef struct student{
char name[20];
int age;
int score;
}Stu;
BOOL cmpByAge(Stu *s1,Stu *s2);
BOOL cmpByAge(Stu *s1,Stu *s2)
{
return s1->age > s2->age;
}
BOOL cmpByName(Stu *s1,Stu *s2);
BOOL cmpByName(Stu *s1,Stu *s2)
{
return strcmp(s1->name, s2->name);
}
BOOL cmpByScore(Stu *s1,Stu *s2);
BOOL cmpByScore(Stu *s1,Stu *s2)
{
return s1->score > s2->score;
}
void sortArr(Stu *s,int count,BOOL (*p)(Stu *,Stu *));
void sortArr(Stu *s,int count,BOOL (*p)(Stu *,Stu *))
{
for (int i = 0 ; i < count - 1; i ++) {
for (int j = 0; j < count - 1 - i; j ++) {
if (p(&s[j],&s[j + 1])) {
Stu temp = {0};
temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
}
int main(int argc, constchar * argv[]) {
Stu s1 = {"aaa",17,80};
Stu s2 = {"bbb",18,70};
Stu s3 = {"ccc",22,60};
Stu s4 = {"ddd",15,90};
Stu stuArr[4] = {s1,s2,s3,s4};
BOOL (*p)(Stu *,Stu *);
printf("请输入0~2,分别按姓名、年龄、成绩排序:\n");
int a = 0;
scanf("%d",&a);
switch (a) {
case 0:
p = cmpByName;
break;
case 1:
p = cmpByAge;
break;
case 2:
p = cmpByScore;
break;
default:
break;
}
sortArr(stuArr, 4, p);
for (int i = 0; i < 4; i ++) {
printf("%s,%d,%d\n",stuArr[i].name,stuArr[i].age,stuArr[i].score);
}
4.函数返回值是指针函数
typedef int (*PFUN)(int,int);
相当于把这个类型的指针 int (*) ( int,int ) 定义一个新名字 PFUN