1. const指针
const关键字,常量(只读)
const int *p; int const *p; int *const p; const int *const p; int const *const p;
1和2是等价的:const修饰p,指针变量p的值可以改变, 但不能利用指针修改指向空间中的值
3:const修饰p,指针变量p的值不能改变,但可以利用指针变量p修改指向空间中的值(一定要对指针初始化)
4和5是等价的:const修饰p和*p,指针变量p的值不能改变,也不能利用*p改变直系那个空间中的值(一定要初始化)
2. void
//高精度 int *p; double *p; char *p; //低精度 void *p //p保存内存地址
int * 、double * 、char * 转换为void * 需要强制类型转换
void *转换为int * 、double * 、char * 不需要强制类型转换
strcpy拷贝字符串
memcpy拷贝一段内存空间
3. 函数指针和指针函数
指针函数:是函数,函数的返回值类型是指针类型
函数指针:是指针,指针指向了函数
1. 指针函数:
局部变量的地址不能返回,因为局部变量会随函数作用域结束被回收,虽然能获得返回的地址,但地址对应的空间已经被回收过了
将函数的返回值作为下一个函数的参数
2. 函数指针:
int (*Fun)(int a, int b) = NULL;
定义函数指针变量Fun,占8个字节空间,指向int返回值2个int参数的函数
练习:
1. 定义一个指针函数,实现字符串数组用来拷贝的strcpy函数
#includechar *Mystrcpy(char *pdst, char *psrc) { char *pret = pdst; while(*psrc != '\0') { *pdst = *psrc; psrc++; pdst++; } *pdst = '\0'; return pret; } int main(void) { char str[32] = {0}; char dst[32] = {0}; Mystrcpy(dst, Mystrcpy(str, "hello world")); printf("str = %s\n",str); printf("dst = %s\n",dst); }
2. 利用函数指针,实现数组的排序(升序、降序、绝对值升序、绝对值降序)
#include#include int InputArray(int *parray, int len) { int i = 0; for(i = 0; i < len; i++) { scanf("%d",&parray[i]); } return 0; } int SortArray(int *parray, int len, int (*pcompay)(int, int)) { int i = 0; int j = 0; int tmp = 0; for(j = 0; j < len-1; j++) { for(i = 0; i < len-1-j; i++) { if(pcompay(parray[i], parray[i+1])) { tmp = parray[i]; parray[i] = parray[i+1]; parray[i+1] = tmp; } } } return 0; } int OutputArray(int *parray, int len) { int i = 0; for(i = 0; i < len; i++) { printf("%d ",parray[i]); } printf("\n"); return 0; } int AscCompare(int num1, int num2) { if(num1 > num2) { return 1; } return 0; } int DescCompare(int num1, int num2) { if(num1 < num2) { return 1; } return 0; } int AbsAscCompare(int num1, int num2) { if(abs(num1) > abs(num2)) { return 1; } return 0; } int AbsDeascCompare(int num1, int num2) { if(abs(num1) < abs(num2)) { return 1; } return 0; } int main(void) { int a[5] = {0}; InputArray(a, 5); SortArray(a, 5, AscCompare); printf("升序: "); OutputArray(a, 5); SortArray(a, 5, DescCompare); printf("降序: "); OutputArray(a, 5); SortArray(a, 5, AbsAscCompare); printf("绝对值升序: "); OutputArray(a, 5); SortArray(a, 5, AbsDeascCompare); printf("绝对值降序: "); OutputArray(a, 5); return 0; }
4. C语言中二级指针使用场景:
1. 指针数组传参时:
char *str[5]; int Fun(char **ppstr, int len);
2. 函数体内想修改函数体外指针变量值的时候,要传递指针变量的地址即二级指针
char *p = NULL; int Fun(char **pp);
5. 构造数据类型:
数据类型:
1. 基本数据类型:
int、double、 char
2. 构造数据类型:
1. struct 结构体
2.union 共用体
3. enum 枚举
1. 结构体:
1. 结构体类型的定义
struct 结构体名 { 数据类型1 成员变量1; 数据类型2 成员变量2; 数据类型3 成员变量3; ...... };
2. 结构体变量的定义
数据类型 变量名; 数据类型 *指针变量名;
3. 结构体变量的初始化
1. 全部初始化:
struct students = {"zhangsan", 'm', 19, 100};
2. 局部初始化:
struct student stu = { .name = "lisi", .score = 90, };
4. 结构体成员变量的访问:
. :结构体变量类型访问成员变量使用 .
->:结构体指针类型访问成员变量使用 ->
整体类型由成员变量类型决定
作业:
1. 定义一个结构体包含年-月-日三个成员,从终端接收年月日信息存放到结构体中,计算该年为第几天?计算该年剩余多少天?打印年月日信息
#include#include struct data { int year; int mon; int day; }; int IsLeepYear(int Year) { if(Year % 400 == 0) { return 1; } else if(Year % 4 ==0 && Year % 100 != 0) { return 1; } else { return 0; } } int GetDayOfYear(int Year, int Mon, int Day) { int i = 0; int NowDay = 0; for(i = 0; i < Mon; i++) { if(i==1 || i==3 || i==5 || i==7 || i==8 || i==10 || i==12) { NowDay += 31; } else if(i == 4 || i ==6 || i == 9 || i==11) { NowDay += 30; } else if(i == 2) { if(IsLeepYear(Year)) { NowDay += 29; } else { NowDay += 28; } } } NowDay += Day; return NowDay; } int GetLeftDayOfYear(int Year,int Mon,int Day) { int RemDay = 0; if(IsLeepYear(Year)) { RemDay = 366 - GetDayOfYear(Year, Mon, Day); } else { RemDay = 365 - GetDayOfYear(Year, Mon, Day); } return RemDay; } int main(void) { struct data d; int NowDay = 0; int RemDay = 0; memset(&d, 0, sizeof(d)); scanf("%d%d%d", &d.year, &d.mon, &d.day); NowDay = GetDayOfYear(d.year, d.mon, d.day); RemDay = GetLeftDayOfYear(d.year, d.mon, d.day); printf("%d-%d-%d是此年的第%d天,还剩余%d天\n", d.year, d.mon, d.day, NowDay, RemDay); return 0; }
2. 封装一个函数,给定一个数字字符串转换成其对应的整型数
如:“123456” 得到123456
#include#include int MyAtoi(char *pstr) { int sum = 0; while(*pstr != '\0') { sum *= 10; sum += (*pstr-'0'); pstr++; } return sum; } int main(void) { char num[32] = {0}; int sum = 0; gets(num); sum = MyAtoi(num); printf("%d\n",sum); return 0; }