1.指针函数和函数指针
1.1 指针函数
指针函数是函数,函数的返回值是指针
- 不能返回局部变量的地址
- 指针函数返回的地址可以作为下一个函数调用的参数
1.2 函数指针
函数指针是指针,指针指向一个函数
#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 x, int y, int (*p)(int x, int y)) { return p(x,y); } int main(void) { int (*p)(int x, int y) = 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",jisuanqi(num1, num2, p)); //p指向某函数 return 0; }
2.二级指针
2.1 定义
二级指针是指向一级指针变量的指针
int **q; 定义一个指针变量q,占8个字节空间,指向ige指针变量空间,即指向一级指针变量的指针
2.2 使用场景
1.函数体内部想修改函数体外部指针变量的值时,需要传递指针变量的地址即二级指针
2.指针数组传参,数组的数组名是指向数组第一个元素的指针,第一个元素是指针,所以数组名为指向指针的指针即二级指针
3.指针数组和数组指针
3.1 定义
1.指针数组:是数组,数组的每个元素是指针
2.数组指针:是指针,指针指向整个数组
int *a[5]; 定义一个数组,占40个字节空间,数组名为a,每个元素都是int *型的指针 int (*a)[5]; 定义一个指针,占8个字节,指针变量名为a,是指向数组为20个字节空间的指针
3.2 指针数组
int *a[5]; char *pstr[5];
- 存放字符串使用字符型数组,操作字符串使用指针
- 存放字符串数组使用字符型二维数组,操作字符串数组使用指针数组
3.3 利用指针数组操作二维数组中的字符串实现排序
- 二维数组存放字符串数组
- 指针数组元素变化代替二维数组字符串变化,提高程序效率
3.4 数组指针
- 对一维数组数组名&:值不变 ,类型升级为指向整个数组的指针
- 对指针数组*:值不变,类型降级为指向数组第一个元素的指针
int a[5] = {1,2,3,4,5}; a == &a[0]; a == int *
注意:两种情况a不能理解为int *
- sizeof:获得数据类型、变量所占字节
- &:&int * -> int ** &a -> int (*p)[5]
第十一行:&a+1指向下一个数组的首地址,再强制转换为int *型,再减一即减去四个字节,回到数组a的第五个元素,故打印出来为5
3.5 数组指针的使用场景
1.一维数组和指针的关系
- 数组的数组名是指向数组第一个元素的指针常量
int a[5] = {1,2,3,4,5}; int *p = NULL; p = &a[0]; p = a; a == &a[0]; a[n] == *(a+n) == *(p+n) == p[n]
2.二维数组和指针的关系
- 数组的数组名是指向数组第一行的数组指针
int a[2][3] = {1,2,3,4,5,6}; int *p = NULL; int (*q)[3] = NULL; p = &a[0][0]; p = a[0]; p = *a; q = a; a:指向数组第一行元素的数组指针 int (*)[3] a[0]:指向a[0][0]的指针 int * a[1]:指向a[1][0]的指针 int * 访问数组第m行第n列元素的方式: a[m][n] *(a[m]+n) *(*(a+m)+n) *(p+m*N+n) *(*(q+m)+n) *(q[m]+n) q[m][n]
作业
1.封装一个函数,将字符串“12345”转换成整形12345
2.封装函数实现mystrlen,mystrcpy,mystrcat,mystrcmp功能
3.从终端接收五个字符串,对他们排序后输出
#include <stdio.h>
int ToNum(char *a)
{
int i = 0;
int num[32] = {0};
int sum = 0;
while(*a != '\0')
{
num[i] = *a - '0';
sum = sum * 10 + num[i];
i++;
a++;
}
return sum;
}
int main(void)
{
char a[32] = "12345";
printf("outnum = %d\n",ToNum(a));
return 0;
}
#include <stdio.h>
int mystrlen(const char *str)
{
int i = 0;
while(*str != '\0')
{
str++;
i++;
}
return i;
}
char *mystrcpy(const char *pstr, char *pret)
{
char *ret = pret;
while(*pstr != '\0')
{
*pret = *pstr;
pret++;
pstr++;
}
return ret;
}
int mystrcmp(const char *pstr, const char *pdst)
{
while(*pstr == *pdst)
{
if(*pstr == '\0')
{
return 0;
}
pstr++;
pdst++;
}
return *pstr - *pdst;
}
char *mystrcat(char *pstr, const char *pdst)
{
int len = mystrlen(pstr);
char *str = pstr;
pstr += len;
while(*pdst != '\0')
{
*pstr = *pdst;
pstr++;
pdst++;
}
return str;
}
int main(void)
{
char str[100] = {0};
char dst[100] = {0};
char ret[100] = {0};
gets(str);
gets(dst);
printf("strlen:len_str = %d\n",mystrlen(str));
printf("strcpy:ret_cpy_str = %s\n",mystrcpy(str,ret));
if(mystrcmp(str,dst) > 0)
{
printf("str > cmp\n");
}
else if(mystrcmp(str,dst) == 0)
{
printf("str = dst\n");
}
else
{
printf("str < dst\n");
}
printf("strcat:new_str = %s\n",mystrcat(str,dst));
return 0;
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char a[5][100] = {0};
char *pstr[5] = {a[0], a[1], a[2], a[3], a[4]};
char tmp[100] = {0};
int i = 0;
int j = 0;
for(i = 0; i < 5; i++)
{
gets(a[i]);
}
for(j = 0; j < 4; j++)
{
for(i = 0; i < 4-j; i++)
{
if(strcmp(pstr[i], pstr[i+1]) > 0)
{
strcpy(tmp,pstr[i]);
strcpy(pstr[i], pstr[i+1]);
strcpy(pstr[i+1], tmp);
}
}
}
for(i = 0; i < 5; i++)
{
printf("a[%d] = %s\n",i,a[i]);
}
return 0;
}