目录
一、字符指针变量
字符指针char*
&符号名 符号名,这都是获取的是首元素地址。
int main()
{
char a[] = "abcdef";
char* pc = &a;
*pc = 'w';
return 0;
}
//输出wbcdef
char* pc = &a;获取的只是字符串的首地址,并没有获取整个数组的地址。
int main ()
{
const char* pstr = "hello bit.";
printf("%s\n", pstr);
return 0;
}
在这一行代码中,我们是否把hello bit整个字符串地址放入到pstr指针里面了吗?并没有,pstr只是获取了字符串中首元素的地址。
我们来分析以下题目,大家可以先思考。
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char* str3 = "hello bit.";
const char* str4 = "hello bit.";
if (str1 == str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if (str3 == str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
这个题目是比较的地址是否相同。
str1与str2创建的变量不是在一个地址里面。
str3与str4因为是指针,这两个指针指向的是同一个字符串。
以上题目输出
str1 and str2 are not same
str3 and str4 are same
二、数组指针变量
指针获取的是指向类型变量的地址,指针需要获得整个数组的地址。
int* p1;//存放的是整型变量地址,能够指向整型数据的指针。
char* p2;//存放的是字符变量地址,能到指向字符数据的指针。
double* p3;//存放的是浮点型变脸的地址,能够指向浮点型数据的指针。
那么如何获取数组的地址并存放到指针里呢?
int main()
{
int arr[5] = { 1,2,3,4,5 };
int(*p)[5] = &arr;
return 0;
}
在调试这段代码的时候,我们看见p已经接收了整个数组,数组的类型已经改变成int[5]*
三、⼆维数组传参的本质
void add(int arr[3][3], int r, int s)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < s; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
add(arr, 3, 3);
return 0;
}
//输出
1 2 3
4 5 6
7 8 9
我们以往想打印出二维数组是使用这种方法来实现打印的。
这是一个二维数组,二维数组是一个连续存放的数组,我可以把二维数组想成一条直线。
这一个3行5列的数组,arr[0]对应的是第一行首元素的地址,arr[1]对应的是第二行首元素的地址。
第一行数组指针类型是int (*)[5],每一行里有五个数
所以二维数组的本质也是传递了地址,传递的地址是一个每一行的数组地址。
void test(int(*p)[5], int r, int s)
{
for (int i = 0; i < r; i++)
{
for (int j = 0; j < s; j++)
{
printf("%d ", (*(*p+i)+j));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };
test(arr, 3, 5);
return 0;
}
//输出
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
void test(int* arr[5], int r, int s),每一行数组中元素的个数为5,使用int (*p)[5]是为了与二维数组‘arr’的每一行的结构匹配
四、函数指针变量
创建一个指针,指针指向的是一个函数。
int add(int x, int y)
{
return x + y;
}
int main()
{
int sz = add(3, 5);
printf("%d\n", sz);
return 0;
}
在以前我们都是直接把函数给传参过去。
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*p)(int x, int y) = add;
printf("%d\n", p(3,5));
return 0;
}
//输出
8
int (*p)(int x, int y) = add; p中存放了函数add的地址,我们就可以通过p直接使用add函数。
int (*)(int x, int y)
int (*)(int, int)
函数指针以上两种写法都可以,看函数需要什么类型的参数。
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*p)(int x, int y) = add;
printf("%d\n", p(3,5));
printf("%d\n", (*p)(4, 6));
return 0;
}
//输出
8
10
以下两种写法都是可以的,推荐使用第一种写法,看起来比较清晰
printf("%d\n", p(3,5));
printf("%d\n", (*p)(4, 6));
五、typedef 关键字
typedef可以讲类型重命名,可以把复杂类型简化成简单。
typedef unsigned int uint;
int main()
{
unsigned int a = 10;
uint b = 30;
return;
}
在这段代码中,把unsigned int给重命名uint。
可以把int*给重命名
typedef int* test;
int(*)[5]也可以给重命名
typedef int(*add)[10];
我们给重命名add,在数组指针里,我们需要在*的右边命名。
int (*)(int,int)同样也能重命名
typedef int(*fun)(int,int);
把int (*)(int,int)给重命名了fun,函数指针跟数组指针一样,都要把重新命名的名字写在*旁边
六、函数指针数组
函数指针数组是把指向函数的指针放一个数组里面里面,创建一个指针指向这个数组。
int add(int x, int t)
{
return x + y;
}
int sub(int x, int t)
{
return x - y;
}
int mul(int x, int t)
{
return x * y;
}
int div(int x, int t)
{
return x / y;
}
int main()
{
int (*p[5])(int, int) = { add,sub,mul,div };
return 0;
}
int (*p[5])(int, int) = { add,sub,mul,div };这一行代码就是函数指针数组,使用了我们前面学习的函数指针,指针数组,
标签:return,int,C语言,add,数组,printf,指针 From: https://blog.csdn.net/m0_62048999/article/details/140923943