1.二级指针:
1.函数体内修改函数体外指针变量的值
2.指针数组的数组名是指向数组第一个元素的指针即二级指针
C语言中:
指针数组传参二级指针和长度
二维数组传参数组指针和长度
char str[5][32];
int fun(char (*p)[32], int len);
char *pstr[5];
int fun(char **ppstr, int len);
#include <stdio.h>
#include <string.h>
int InputArray(char (*pstr)[32], int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
gets(pstr[i]);
}
return 0;
}
int OutputArray1(char (*pstr)[32], int len)
{
int i = 0;
printf("========== 二维数组 ==============\n");
for (i = 0; i < len; i++)
{
printf("%s\n", pstr[i]);
}
return 0;
}
int OutputArray2(char **ppstr, int len)
{
int i = 0;
printf("========== 指针数组 ==============\n");
for (i = 0; i < len; i++)
{
printf("%s\n", ppstr[i]);
}
return 0;
}
int BubbleSort1(char **ppstr, int len)
{
int i = 0;
int j = 0;
char *ptmp = NULL;
for (j = 0; j < len-1; j++)
{
for (i = 0; i < len-1-j; i++)
{
if (strcmp(ppstr[i], ppstr[i+1]) > 0)
{
ptmp = ppstr[i];
ppstr[i] = ppstr[i+1];
ppstr[i+1] = ptmp;
}
}
}
return 0;
}
int BubbleSort2(char (*pstr)[32], int len)
{
int i = 0;
int j = 0;
char temp[32] = {0};
for (j = 0; j < len-1; j++)
{
for (i = 0; i < len-1-j; i++)
{
if (strcmp(pstr[i], pstr[i+1]) > 0)
{
strcpy(temp, pstr[i]);
strcpy(pstr[i], pstr[i+1]);
strcpy(pstr[i+1], temp);
}
}
}
return 0;
}
int main(void)
{
char str[5][32] = {0};
char *pstr[5] = {str[0], str[1], str[2], str[3], str[4]};
InputArray(str, 5);
BubbleSort2(str, 5);
BubbleSort1(pstr, 5);
OutputArray1(str, 5);
OutputArray2(pstr, 5);
return 0;
}
2.函数指针和指针函数:
指针函数是函数,函数的返回值是指针
int *fun(int x, int y);
#include <stdio.h>
#include <string.h>
char *fun(char *pstr)
{
strcpy(pstr, "hello world");
return pstr;
}
int main(void)
{
char str[32] = {0};
char *p = NULL;
p = fun(str);
printf("p = %s\n", p);
printf("%s\n", str);
return 0;
}
Strcpy完整代码实现:
#include <stdio.h>
#include <string.h>
char *MyStrcpy(char *pdst, const char *psrc)
{
char *pret = pdst;
while (*psrc != '\0')
{
*pdst = *psrc;
pdst++;
psrc++;
}
*pdst = '\0';
return pret;
}
int main(void)
{
char src[32] = {0};
char dst[32] = {0};
MyStrcpy(dst, MyStrcpy(src, "hello world"));
printf("src = %s\n", src);
printf("dst = %s\n", dst);
return 0;
}
函数指针是指针,指针指向一个函数
int (*p)(int, int);
#include <stdio.h>
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
int Jisuanqi(int num1, int num2, int (*pfun)(int, int))
{
return pfun(num1, num2);
}
int main(void)
{
int (*p)(int, int) = NULL;
int num1 = 0;
int num2 = 0;
char op = 0;
scanf("%d %c%d", &num1, &op, &num2);
switch (op)
{
case '+':p = Add;break;
case '-':p = Sub;break;
case '*':p = Mul;break;
case '/':p = Div;break;
}
printf("Ret = %d\n", p(num1, num2));
if ('+' == op)
{
printf("%d\n", Jisuanqi(num1, num2, Add));
}
else if ('-' == op)
{
printf("%d\n", Jisuanqi(num1, num2, Sub));
}
else if ('*' == op)
{
printf("%d\n", Jisuanqi(num1, num2, Sub));
}
else if ('/' == op)
{
printf("%d\n", Jisuanqi(num1, num2, Div));
}
return 0;
}
3.指针函数:
返回值为指针的函数
注意:
1.指针函数不能返回局部变量的地址
4.void *指针
void 缺省类型
void *只表示类型地址,没有指向空间大小的含义
主要用于函数传参和返回值使用
void a; //错
void *p = 0x2000; //对
char *p = 0x2000;
double *p = 0x2000;
int *p = 0x2000;
注意:
1.char *、int *、double * 转换为void *时需要强制类型转换
2.void *转换为char *、int *、double *时不需要强制类型转换
5.函数指针:
函数指针是指针,占8个字节空间,指向函数
=========================================================================
构造数据类型:
1.数据类型
1.基本数据类型: short int long float double
2.构造数据类型: 结构体、共用体(联合体)、枚举
2.结构体:
1.结构体类型的定义:
struct 结构体名
{
数据类型1 成员变量1;
数据类型2 成员变量2;
数据类型3 成员变量3;
...
};
2.结构体变量的定义:
数据类型 变量名;
3.结构体变量的初始化:
1.全部初始化:
struct student s = {"zhangsan", 'm', 19, 100};
2.局部初始化:
struct student s = {
.name = "zhangsan",
.score = 100,
};
4.结构体成员的访问:
. :结构体变量类型访问成员变量
-> :结构体指针类型访问成员变量
#include <stdio.h>
#if 1
struct mtime
{
int hour;
int min;
int sec;
};
struct mdate
{
int year;
int mon;
int day;
};
struct datetime
{
struct mdate md;
struct mtime mt;
};
#else
struct datetime
{
struct mdate
{
int year;
int mon;
int day;
}md;
struct mtime
{
int hour;
int min;
int sec;
}mt;
};
#endif
struct student
{
char name[32];
char sex;
int age;
int score;
};
int main(void)
{
struct student a = {"zhangsan", 'm', 20, 80};
struct datetime dt = {{2024, 7, 25}, {16, 32, 30}};
struct student b = {
.name = "zhangsan",
.score = 100,
};
struct datetime dt2 = {
.md = {
.mon = 7,
.day = 25,
},
};
struct student *p = NULL;
struct datetime *pdt = NULL;
printf("姓名:%s\n", a.name);
printf("性别:%c\n", a.sex);
printf("年龄:%d\n", a.age);
printf("成绩:%d\n", a.score);
printf("%04d-%02d-%02d %02d:%02d:%02d\n", dt.md.year, dt.md.mon, dt.md.day, dt.mt.hour, dt.mt.min, dt.mt.sec);
p = &a;
printf("姓名:%s\n", p->name);
printf("性别:%c\n", p->sex);
printf("年龄:%d\n", p->age);
printf("成绩:%d\n", p->score);
pdt = &dt;
printf("%04d-%02d-%02d %02d:%02d:%02d\n", pdt->md.year, pdt->md.mon, pdt->md.day, pdt->mt.hour, pdt->mt.min, pdt->mt.sec);
return 0;
}
结构体访问成员变量最终的类型由成员变量的类型决定