1. 二维数组和指针的关系
1. 二维数组的数组名是指向第一行所有元素的一个数组指针 —— char (*str)[32]
2. 对二维数组数组名取*,获得指向二维数组第一行第第一个元素的指针,即数组的首地址
3. 二维数组访问第m行第n列元素——int a[2][3]
a[m][n];
*(a[m]+n)
*(*(a+m)+n)
2. 二维数组的传参
传递数组指针和长度
char str[5][32] = {0};
int fun(char (*pstr)[32], int len);
3. 指针数组的传参
传递二级指针和长度
char *pstr[5] = {"hello", "world", "how", "are", "you"};
int fun(char **ppstr, int len);
4. 指针函数和函数指针
4.1 指针函数(返回指针的函数)
char *MyStrcpy(char *pdst, const char *psrc)
指针函数是函数,函数的返回值是指针(不能返回局部变量的地址,无效)
1. strcpy返回值为dst的地址(即返回指向dst的指针)
#include <stdio.h>
#include <string.h>
int main(void)
{
char src[32] = {0};
char dst[32] = {0};
char *tmp = NULL;
gets(src);
tmp = strcpy(dst, src);
printf("dst = %p\n", dst);
printf("tmp = %p\n", tmp);
return 0;
}
2. 指针函数的例子(指针返回指针的指针函数能作为指针嵌套使用)
#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};
char tmp[32] = {0};
gets(src);
// MyStrcpy(dst, src);
// MyStrcpy(tmp, dst);
MyStrcpy(tmp, MyStrcpy(dst, src));
// strcpy(tmp, strcpy(dst, src));
printf("dst = %s\n", dst);
printf("tmp = %s\n", tmp);
return 0;
}
4.2 函数指针(指向函数的指针,一个函数的函数名为一个函数指针,动态操作函数)
int (*fun)(int, int)——传参格式
函数指针是指针,指针指向一个函数
例1:
#include <stdio.h>
int add(int a, int b)
{
return a - b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a * b;
}
int div(int a, int b)
{
return a / b;
}
int main(void)
{
int (*pfun)(int, int) = NULL;
pfun = add;
printf("%p\n", pfun);
return 0;
}
例2:
#include <stdio.h>
#include <stdlib.h>
void InputArray(int *p, int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
scanf("%d", &p[i]);
}
}
void OutputArray(int *p, int len)
{
int i = 0;
for (i = 0; i < len; i++)
{
printf("%d ", p[i]);
}
putchar('\n');
}
int Asc(int a, int b)
{
return a > b;
}
int Desc(int a, int b)
{
return a > b;
}
int AbsAsc(int a, int b)
{
return abs(a) > abs(b);
}
int AbsDesc(int a, int b)
{
return abs(a) > abs(b);
}
void BubbleSort(int *p, int len, int (*pfun)(int, int))
{
int i = 0;
int j = 0;
int tmp = 0;
for (i = 0; i < len-1; i++)
{
for (j = 0; j < len-1-i; j++)
{
if (pfun(p[j], p[j+1]))
{
tmp = p[j];
p[j] = p[j+1];
p[j+1] = tmp;
}
}
}
}
int main(void)
{
int a[5] = {0};
int len = 5;
InputArray(a, len);
BubbleSort(a, len, AbsAsc);
OutputArray(a, len);
return 0;
}
注意:函数的函数名是指向函数的指针(实质是指向函数内存空间的首地址)(传参的格式为函数指针)
5. 二级指针的使用范围
5.1 传指针数组
5.2 函数体内部修改指针变量的值
例子
#include <stdio.h>
int fun(char **pptmp)
{
*pptmp = "hello world";
return 0;
}
int main(void)
{
char *p = NULL;
fun(&p);
printf("p = %s\n", p);
return 0;
}
6. 关于字符串的输出
1. printf("%s\n", str); 字符串的打印只需要传入字符串的首地址,打印函数会依次遍历直到遇到 ' \0 '停止
2. strlen、strcpy、strcmp、strcat 在使用时只需要传递字符串的首地址函数即可对其进行操作,直到遇到 ' \0 ' 完成对字符串的操作