指针
来源:互联网 发布:淘宝代刷信誉平台 编辑:程序博客网 时间:2024/05/16 05:35
指针
一、变量的内存地址
先明确两个概念:
变量的地址:变量在内存中所占空间的首地址;
变量的值:变量在存储空间的存放的地址;
二指针变量的定义和初始化
1、指针变量的定义:
类型关键字 *指针变量名
int *pa;int *pa, *pb;
- 1
- 2
- 1
- 2
为了避免忘记给指针初始化带来的潜在危险,习惯上在定义指针变量的时候,将其初始化为NULL:
int *pa = NULL;
- 1
- 1
2、指针的初始化
指针变量只能指向同一基类型的变量
int a = 10;int *pa;pa = &a;
- 1
- 2
- 3
- 1
- 2
- 3
int a = 10;int *pa = &a;
- 1
- 2
- 1
- 2
三、间接寻址运算符
通过变量名和变量的地址存取变量的内容的访问方式,叫直接寻址;
通过指针变量存取他所指向的变量额度访问方式,叫间接寻址;
获取变量地址需要取址操作符‘&’;
指针运算符或者是间接寻址运算符‘*’;
#include "stdio.h"int main(){ int a = 0; float b = 3.0; char c = 'a'; int *pa = &a; float *pb = &b; char *pc = &c; printf("a = %d, a = %d, *a = %d, *a = %d", a, *pa, &a, pa); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
结果是:a = 0, a = 0, *a = 10485300, *a = 10485300
指针使用的准侧就是:
永远不要使用未初始化的指针变量;
四、按值调用与模拟按引用调用
普通变量做函数参数其实就是按值调用。
下面看一组代码:
#include "stdio.h"void fun(int a){ printf("a = %d\n", a); a = 2;}int main(){ int a; printf("Please input a number:\n"); scanf("%d", &a); fun(a); printf("a = %d", a); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
结果是:
Please input a number:
5(输入)
a = 5(输出)
a = 5
上面这段代码说明普通变量是按值引用的,我们更改函数的形参并未影响到实参的变化,这是因为你传给函数形参的值只是调用函数中实参的副本而已.
通过向函数传递某个值的地址值可以在被调函数中更改实参的值,因为相当于模拟了c++中的按引用调用,所以这里称为模拟按引用调用;
下面我们来简单的更改一下代码:
#include "stdio.h"void fun(int *a){ printf("a = %d\n", *a); *a = 2;}int main(){ int a; printf("Please input a number:\n"); scanf("%d", &a); fun(&a); //向函数传递地址值; printf("a = %d", a); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
结果是:
Please input a number:
5(输入)
a = 5(输出)
a = 2
看完模拟按引用调用的第一个作用:在另一个函数中更改实参的值之后,我们来看他的第二个作用:
#include "stdio.h"int fun(int a){ printf("a = %d\n", a); a = 2; return a;}int main(){ int argc = 1; printf("a = %d\n", argc); argc = fun(argc); printf("a = %d\n", argc); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
结果是:
a = 1
a = 1
a = 2
没有想到吧,运用return 我们可以达到像上面一样的效果;所以呢应用返回值,我们也可以在被调函数中修改实参的值;这是为什么呢?是因为我们在fun函数中应用了return语句,程序执行到return就会结束,也就是程序根本没有机会去执行printf(“a = %d\n”, argc);和他以后的语句。
好吧,言归正传我们要说的是第二个用法,就是利用模拟按引用调用从函数中返回多个值;
#include "stdio.h"void Swap(int *a, int *b);int main(){ int a; int b; printf("please input a and b:\n"); scanf("%d%d", &a, &b); Swap(&a, &b); //向函数传递地址值; printf("a = %d\nb = %d\n", a, b); return 0;}void Swap(int *a, int *b){ int temp; temp = *a; *a = *b; *b = temp;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
结果是:
please input a and b:
1 5(输入)
a = 5(输出)
b = 1
五、用指针变量做函数地址值
#include "stdio.h"#define N 40void findMax(int *pa, long *pb, int n, int *maxscore, long *maxnum);int main(){ int score[N]; int maxScore; int i, n; long num[N], maxNum; printf("How many students:\n"); scanf("%d", &n); printf("Please input studentID and score:\n"); for(i=0;i<n;i++) { scanf("%ld%d", &num[i], &score[i]); } findMax(score,num, n, &maxScore, &maxNum); //将数组和变量的地址传给被调函数; printf("maxNum = %ld\nmaxScore = %d\n", maxNum, maxScore); return 0;}void findMax(int *pa, long *pb, int n, int *maxscore, long *maxnum) //定义形参指针{ int i,score; *maxscore = *pa; for(i=0;i<n;i++) { if(*maxscore < *pa) { *maxscore = *pa; *maxnum = *pb; } pa++; pb++; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
结果是:
How many students:
4
Please input studentID and score:
121212 90
131313 91
141414 92
151515 93
maxNum = 151515
maxScore = 93
这段代码可能有点超出本篇的范围了,如果看不懂请参见数组与指针(一)和数组与指针(二);
五、函数指针
看了这么多,大家应该也累了,所以我们上段代码,把这个solve了!
#include "stdio.h"int add(int a, int b){ return a+b;}int sub(int a, int b){ return a-b;}int caculate(int a, int b, int (*calculate)(int a, int b)){ int result; result = (*calculate)(a, b); return result; }int main(){ int a, b; int result_1, result_2; printf("Please input a and b:\n"); scanf("%d%d", &a, &b); result_1 = caculate(a, b, add); result_2 = caculate(a, b, sub); printf("a + b = %d\n", result_1); printf("a - b = %d\n", result_2); return 0;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
结果是:
Please input a and b:
1 5(输入)
a + b = 6(输出)
a - b = -4
大家也看到了,函数指针就是这样神奇!
函数指针就是指向函数指针,在前面的知识中我们知道,一个数组名就是存储数组第一个元素的内存地址,同样的道理,一个函数名就是这个函数代码在内存中的起始地址;上面的代码中,我想你也知道函数指针的价值:把一些重复性的工作放在母函数中,把核心的子函数单独放出来,其核心价值就是减少重复代码。
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 指针
- 实现ViewPager多种实现
- Django之处理用户上传的文件
- Spring createBean过程中BeanPostProcessor的处理机会
- 【玩转SQLite系列】(五)SQLite数据库优化
- pat甲1011. World Cup Betting(水题)
- 指针
- Big Event in HDU-01背包(dp思想)
- Hibernate检索策略
- JDBC层次结构和基本构成
- 数据库(二)关系数据库
- Python计算机视觉:对图片进行格式转换
- 内存泄漏分析
- React Native android release 发布
- 基于ODPS的SQL语句