大家好,欢迎来到IT知识分享网。
每日一图:
本篇内容:
- 1.字符指针
- 2.指针数组
- 3.数组指针
-
- 3.1数组指针的定义
- 3.2&数组名和数组名的区别
- 3.3数组指针的使用
- 4.数组参数和指针参数
-
- 4.1一维数组传参
- 4.2二维数组传参
- 4.3一级指针传参
- 4.4二级指针传参
- 5.函数指针
- 6.函数指针数组
-
- 简易计算器
- 7.指向函数指针数组的指针
1.字符指针
int main() {
char ch = "a"; char* pc = &ch; return 0; }
这里的pc就是一个字符指针变量,这种方法是让我们的字符指针指向了一个字符变量。
另一种使用方式如下:
把字符串首字符的地址赋给了一个指针。
int main() {
const char* p = "Hello World"; return 0; }
因为这个字符串是一个常量字符串(不能被修改)所以在char*前面加一个const会更加严谨。
2.指针数组
指针数组就是存放指针的数组或存放地址的数组。
存放字符指针的数组:
int main() {
const char* arr[4] = {
"abcd,qwer,asdf,zxcv" }; return 0; }
这四个字符串的首字符的地址都被放在了指针数组arr中。
打印:
int main() {
const char* arr[4] = {
"abcd","qwer","asdf","zxcv" }; int i = 0; for (i = 0; i < 4; i++) {
printf("%s\n", arr[i]); } return 0; }
存放整形指针的数组:
int main() {
int arr1[5] = {
1,2,3,4,5 }; int arr2[5] = {
2,3,4,5,6 }; int arr3[5] = {
3,4,5,6,7 }; int arr4[5] = {
4,5,6,7,8 }; int* arr[4] = {
arr1,arr2,arr3,arr4 }; return 0; }
打印:
int main() {
int arr1[5] = {
1,2,3,4,5 }; int arr2[5] = {
2,3,4,5,6 }; int arr3[5] = {
3,4,5,6,7 }; int arr4[5] = {
4,5,6,7,8 }; int* arr[4] = {
arr1,arr2,arr3,arr4 }; int i = 0; for (i = 0; i < 4; i++) {
int j = 0; for (j = 0; j < 5; j++) {
printf("%d ", arr[i][j]); } printf("\n"); } return 0; }
3.数组指针
3.1数组指针的定义
数组指针 – 存放数组地址的指针 – 指向数组的指针
数组指针的写法:
int arr[10]; int (*pa)[10] = &arr;
3.2&数组名和数组名的区别
先来看一段代码:
int main() {
int arr[10] = {
1,2,3,4,5,6,7,8,9,10 }; printf("%p\n", arr); printf("%p\n", arr + 1); printf("%p\n", &arr[0]); printf("%p\n", &arr[0] + 1); printf("%p\n", &arr); printf("%p\n", &arr + 1); return 0; }
3.3数组指针的使用
void print1(int(*p)[4],int r,int c) {
int i = 0; for (i = 0; i < r; i++) {
int j = 0; for (j = 0; j < c; j++) {
printf("%d ", (*(p + i))[j]);//或printf("%d ", p[i][j]); } printf("\n"); } } int main() {
int arr[3][4] = {
{
1,2,3,4},{
2,3,4,5},{
6,7,8,9} }; print1(arr, 3, 4); return 0; }
4.数组参数和指针参数
函数的参数应该如何设计呢?
4.1一维数组传参
一维数组传参的时候形参该如何写?
void test(int arr[]) {
} void test(int arr[10]) {
} void test(int* arr) {
} void test2(int* arr[20]) {
} void test2(int** arr) {
} int main() {
int arr[10] = {
0 }; int* arr2[20] = {
0 }; test(arr); test2(arr2); }
以上方法均可
4.2二维数组传参
二维数组传参的时候形参该如何写?
void test(int arr[3][5]) {
} void test(int arr[][5]) {
} //总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。 //因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。 //这样才方便运算。 void test(int(*arr)[5]) {
} int main() {
int arr[3][5] = {
0 }; test(arr); }
以上方法均可
4.3一级指针传参
指针变量传参,指针变量接收
#include <stdio.h> void print(int *p, int sz) {
int i = 0; for(i=0; i<sz; i++) {
printf("%d\n", *(p+i)); } } int main() {
int arr[10] = {
1,2,3,4,5,6,7,8,9}; int *p = arr; int sz = sizeof(arr)/sizeof(arr[0]); //一级指针p,传给函数 print(p, sz); return 0; }
当一个函数的参数部分为一级指针的时候,函数能接收什么参数?
void test(int* p) {
} int main() {
int a = 10; int* p = &a; int arr[10]; test(p);//可以传一级指针 test(arr);//可以传一维数组的数组名 test(&a);//可以传整型变量的地址 return 0; }
4.4二级指针传参
void test(int** ptr) {
printf("num = %d\n", **ptr); } int main() {
int n = 10; int* p = &n; int** pp = &p; test(pp); test(&p); return 0; }
二级指针传参,形参部分用二级指针接收。
当函数的参数为二级指针的时候,可以接收什么参数?
void test(int** p) {
} int main() {
int** ptr; int* pp; int* arr[10]; test(ptr);//可以传二级指针变量 test(&pp);//可以传一级指针变量的地址 test(arr);//可以传指针数组的数组名 return 0; }
5.函数指针
前面我们讲到了数组指针:指向数组的指针。
inr arr[10]; int (*p) [10] = &arr;
那么函数指针是什么呢?其实就是指向函数的指针
其实函数也是有地址的,我们来看下面这条代码:
int Add(int x, int y) {
return x + y; } int main() {
printf("%p\n", &Add); return 0; }
运行效果:
可以看到,我们把Add函数的地址打印了出来。
那么函数指针应该怎么写呢?很简单,我们看下面这条代码:
int Add(int x, int y) {
return x + y; } int main() {
int (*pf)(int,int) = &Add; //pf是一个存放函数地址的指针变量 — 函数指针 return 0; }
int (*pf)(int, int) = Add;
int (*pf)(int, int) = Add; int ret = (*pf)(2, 3);//或int ret = pf(2,3); printf("%d\n", ret);
首先pf是个指针,指针解引用才能找到对应的函数(可以省略为pf,但方便理解我们还是写上:(*pf),调用的时候要传参,那我们就传个2和3:(*pf)(2,3),传过去之后函数计算完结果,那我们就把结果放在ret里面:int ret = (*pf)(2,3);
6.函数指针数组
想要写出函数指针数组,要从函数指针的基础上进行改造。
int (*pf)(int,int) = &Add;//函数指针 int (*pfA[5])(int,int) ={
&Add};//函数指针数组
简易计算器
#include<stdio.h> void menu() {
printf("\n"); printf("* 1.add 2.sub *\n"); printf("* 3.mul 4.div *\n"); printf("* 0.exit *\n"); printf("\n"); } 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 (*pf[5])(int, int) = {
0,Add,Sub,Mul,Div }; //输入1对应Add,输入2对应Sub //输入3对应Mul,输入4对应Div int main() {
int input = 0; int x = 0; int y = 0; int ret = 0; do {
menu(); printf("请选择->"); scanf("%d", &input); if (input == 0) {
printf("退出计算器\n"); break; } else if (input >= 1 && input <= 4) {
printf("请输入两个操作数\n"); scanf("%d %d", &x, &y); ret = pf[input](x, y);//通过输入数调用函数 printf("%d\n", ret); } else {
printf("选择错误,请重新选择\n"); } } while (input); return 0; }
这里的函数指针数组代替了switch函数,简化了很多代码,但是他也有缺点:因为函数指针数组限制了他(函数里的参数类型、返回类型必须一致),所以他只能计算双目操作数。
7.指向函数指针数组的指针
int (*pf[5])(int, int);
这里的pf和[]结合说明他是一个数组,但是我们希望他是指针,那我们就在这个基础上进行修改:
int (*pf[5])(int, int);//函数指针数组 int (*(*ppf)[5])(int, int) = &pf;//ppf - 指向函数指针数组的指针
我们只需要加上*然后再把ppf括起来,这时候ppf就是一个指针了。
以上就是本篇的全部内容了,希望大家看完能有所收获。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120611.html

