瘋子C语言笔记(指针篇)
指针篇
1.基本指针变量
(1)定义
int i,j;
int *pointer_1,*pointer_2;
pointer_1 = &i;
pointer_2 = &j;
等价于
int *pointer_1 = &i,*pointer_2 = &j;
(指针误区: 大家首先应该知道,地址可称为指针,是不可变的;指针变量(上述定义的pointer_1为指针变量)是变量,变量是可变的,和通常的变量相比,它存放的量CPU会当地址来处理)
-------------------------------------------------------
(2)简记
*:取该地址空间存放量,*后面的内容CPU当地址处理;
&:取该变量的地址,&后面的内容CPU当变量来处理;
2.一维数组的指针变量
(1)定义
int a[10];
int *p;
p = &a[0];
等价于 p = a;
a[0]和a都表示该数组的首地址;
(2)指向数组的指针变量也可以带下标,如:p[i]、*(p+i);
(3)数组名a代表数组首元素的地址,它是一个指针常量,它的值在程序运行期间是固定不变的,请不要出现类似a++这样的错误。
3.当用数组名做函数参数时传递给函数的是数组的首元素地址,因此要求形参是指针变量;
归纳:
①:形参、实参都用数组名
int a[10];
f(a,10);
.
.
.
viod (int x[ ] , n)
{...}
简解:编译器遇到形参为数组名会当指针变量来处理,故此程序运行期间形参指向数组a[ ]各个元素,或者理解为形参实参在程序运行区间占用同一段内存空间;
②实参数组名,形参指针变量
int a[10];
f(a,10);
.
.
.
viod (int *x, n)
{...}
简解:函数开始执行x指向数组各个元素
③实参形参都是指针变量
int a[10], *p = a;
f(p , 10);
.
.
.
void f(int *x,int n)
{...}
简介:1. p先指向数组a首元素; 2. p值给x; 3. x指向数组a各个元素;
④实参为指针变量,形参为数组名
int a[10],*p = a;
f(p , 10)
void f(int x[],int n)
{...}
简解:1.形参当指针变量处理,后面同③
4.数组a 的性质
int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}
int 型数据在KEIL编译环境下,占2字节内存
|
表示形式 |
含义 |
地址 |
|
a |
二维数组名,指向一位数组a[0],即0行首地址 |
设2000 |
|
a[0]、*(a+0)、*a |
0行0列元素地址 |
2000 |
|
a+1,&a[1] |
1行0列元素地址 |
2008 |
|
a[1]、*(a+1) |
1行0列元素a[1][0]的地址 |
2008 |
|
a[1]+2、*(a+1)+2、&[1][2] |
1行2列(即a[1][2])元素地址 |
2012 |
|
*(a[1]+2)、*(*(a+1)+2),a[1][2] |
1行2列(即a[1][2])元素值 |
元素13 |
(1)为什么*(a+1)表示第一行的首地址呢?
答:*(a+x)==a[X]; 两者等价。
(2)那么C语言中是怎么造成*(a+x)与a[X]完全等价呢?
答:在一位数组中,*a就是a[0],a+1指向a[1],a+2指向a[2],a+3指向a[3],也就是说
*(a+1)、*(a+2)、*(a+3)分别是a[1]、a[2]、a[3]。在实际代码生成机械码的关系中,两个效应完全等价。
5.对于 int(*p)[4]的解释
答:int(*p)[4]表示p是一个指针变量,它指向包含4个整形元素的一维数组,此时p只能指向一个包含4个元素的一维数组,p不能指向一维数组中的某一个元素,p的值就是该一维数组的起始地址。
P
|
(*p)[0] |
(*p)[1] |
(*p)[2] |
(*p)[3] |
→
由此也可得出
|
指针作为函数参数 |
① 指向变量的指针变量(一般) |
|
② 指向一维数组的指针变量 |
6.while(*from != '\0') == while(*from != 0),CPU在处理时,字符与ASCLL码按相同处理。
7.字符数组与字符指针变量
char str[14];
str = "I Love China"; ×(对字符数组只能对各个元素赋值)
数组只可以在定义时整体赋初值,但不能再赋值语句中整体赋值;
BUT(aber)
char *a;
a = "I Love China"; √(注意赋值给a的不是字符,而是字符串第一个元素的地址)
等价于
char *a = "I Love China";
/******典printf******/
char *format;
format = "a=%d,b=%f\n"; 当字符串处理
printf(format,a,b);
等价于
printf("a=%d,b=%f\n",a,b);
8.指向函数的指针
#include<stdio.h>
void main()
{
int max(int,int);
int(*p)(int,int);
int a,b,c;
p = max;
scanf("%d,%d",&a,&b);
c = (*p)(a,b);
printf("a = %d,b = %d,max = %d\n",a,b,c);
}
(1),“int(*p)(int,int);”用来定义p是一个指向函数的指针变量,*p两端的括号绝对不能省略。
(2),"p = max"的作用是将函数max的入口地址赋给指针变量p。和数组名代表数组首元素地址类似,函数名代表该函数的入口地址。(同理:max++是错误的)
(3),指向函数的指针变量的一般定义形式:
数据类型(*指针变量名)(函数参数表列);
9.用指向函数的指针作函数参数
如:
int a = 1;
int b = 2;
int max(int x,int y)
{______________}
void process(int,int,int(*fun)(int,int)); //声明
process(a,b,max); //引用
10.返回指针值的函数
类型名 *函数名(参数列表);
如:
int *a(int x ,int y);
解释:括号的运算优先级大于*号,及是函数a(int x ,int y )的返回值取地址值;
请区别上题8中的int(*p)(int,int);此为指向函数的指针;
int(*p)(int,int); //指向函数的指针
int *a(int,int); //返回指针值的函数
此两者用法顺序相反
用法:
float *p;
float score[][4] = {{1,2,3,4},{5,6,7,8},{11,12,13,14}};
float *search(float (*pointer)[4],int n);
p = search(score, m);
11.指针数组
(1)定义形式
类型名 * 数组名[数组长度];
如:int *p[4];
请不要写成 int (*p)[4]; 这是指向一维数组的指针变量;
指针数组中每一个量都用作指针变量;
为什么用指针数组?
答:它可以比较适合于用来指向若干个字符串,使字符串处理更加方便灵活。
12.指向指针的指针
(1)定义
char **p;
谨记:*p是**p的地址,p是**p的地址,**p是变量。p和*p都是地址;
p前面有两个*号,*运算符的结合性是从右到左,因此**p相当于*(*p),显然*p是指针变量的定义形式。

13.NULL
#define NULL 0 (这句在stdio.h里面已经有了)
p = NULL;
表示p不指向任一有用单元,应该注意p的值为NULL与未对p赋值是两个不同的概念。前者是有值的(0),不指向任何程序变量,后者虽未对p赋值但并不等于P无值,只是它的值是一个无法预料的值,也就是p可能指向一个事先未指定的单元。这种情况很危险的。因此,在引用指针变量之前应对它赋值。
任何指针变量或地址都可以与NULL作相等或不相等的比较,例如:
if(p == NULL)...
14.指向同一个数组中的指针运算
(1)相减、比较
| a[0] |
| a[1] |
| a[2] |
| a[3] |
| a[4] |
p1指向a[1],p2指向a[3]
那么:
减法:p2 - p1 = 2,但 p1 + p2是无意义的;
比较:指向前面的元素的指针变量“小于”指向后面元素的指针变量。
即:p1 < p2,或者说“p1 < p2”为1(真);
15.void 指针类型
char *p1;
void *p2;
.
.
.
p1 = (char *)p2;
也可:
p2 = (void *)p1;
void用来指向一个抽象的类型数据,将它的值赋给另一个指针变量时要进行强制类型转换使之适合于被赋值的变量的类型。
15.指针类型小结
| 定义 | 含义 |
| int i; | 定义整型变量i |
| int*p; | p为指向整型数据的指针变量 |
| int a[n]; | 定义整型数组a,它有n个元素 |
| int *p[n]; | 定义指针数组p,它有n个指向整型数据的指针元素组成(多) |
| int (*p)[n]; | p为指向含n个元素的一维数组的指针变量(一) |
| int f(); | f为返为整型函数值的函数 |
| int*p(); | p为返回一个指针的函数,该指针指向整型数据 |
| int(*p)(); | p为指向函数的指针,该函数返回一个整型值 |
| int **p; | p是一个指针变量,它指向一个指向整型数据的指针变量 |
下次更新时间2014.10.10
新的理解和见解可留言相互交流,共同学习
瘋子C语言笔记(指针篇)的更多相关文章
- 瘋子C语言笔记(结构体/共用体/枚举篇)
(一)结构体类型 1.简介: 例: struct date { int month; int day; int year; }; struct student { int num; char name ...
- 瘋子C语言笔记 (string)
1.strstr() 函数 搜索一个字符串在另一个字符串中的第一次出现.找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址:如果未找到所搜索的字符串,则返回NULL. 2.strcat() 函数 ...
- 瘋耔java语言笔记
一◐ java概述 1.1 ...
- Scala语言笔记 - 第一篇
目录 Scala语言笔记 - 第一篇 1 基本类型和循环的使用 2 String相关 3 模式匹配相关 4 class相关 5 函数调用相关 Scala语言笔记 - 第一篇 最近研究了下scala ...
- 快速上手系列-C语言之指针篇(一)
快速上手系列-C语言之指针篇(一) 浊酒敬风尘 发布时间:18-06-2108:29 指针的灵活运用使得c语言更加强大,指针是C语言中十分重要的部分,可以说指针是C语言的灵魂.当然指针不是万能的,但没 ...
- C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析
有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...
- C\C++语言重点——指针篇 | 为什么指针被誉为 C 语言灵魂?(一文让你完全搞懂指针)
本篇文章来自小北学长的公众号,仅做学习使用,部分内容做了适当理解性修改和添加了博主的个人经历. 注:这篇文章好好看完一定会让你掌握好指针的本质! 看到标题有没有想到什么? 是的,这一篇的文章主题是「指 ...
- go语言笔记——指针,和C用法以及本质一样,但不支持指针的+-运算!
4.4.2 值类型和引用类型 所有像 int.float.bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值. Go 语言的取地址符是 &,放到一个 ...
- Scala语言笔记 - 第二篇
目录 1 Map的基础操作 2 Map生成view和transform解析 最近研究了下scala语言,这个语言最强大的就是它强大的函数式编程(Function Programming)能力,记录 ...
随机推荐
- 设置一个顺手的Xcode
授权转载,作者:吴白(微博) 手指在键盘上飞速跳跃,终端上的代码也随着飞舞,是的这确实很酷.优秀的程序员总是这么一群人,他们不拘于现状,不固步自封,他们喜欢新奇的事,他们把自己发挥到极致. 指法攻略 ...
- remi
很简单呀,又不用自己编译.用 http://rpms.remirepo.net/ 这个 remi 的包,直接 yum install php-swoole 就完事了 安装remi包也很简单, yum ...
- Yii2 关闭和打开csrf 验证 防止表单多次重复提交
原文地址:http://blog.csdn.net/terry_water/article/details/52221007 1.在Yii2配置中配置所有:所有的controller都将关闭csrf验 ...
- CSS之viewport 1
在这个迷你系列的文章里边我将会解释viewport,以及许多重要元素的宽度是如何工作的,比如<html>元素,也包括窗口和屏幕. 这篇文章是关于桌面浏览器的,其唯一的目的就是为移动浏览器中 ...
- Android APP压力测试-Monkey
压力测试-Monkey学习 Monkey测试特点 什么是Monkey test? 如其名,像猴子一样,虽然什么都不懂,但是可以乱点一通,可以理解为压力测试.在规定的时间或次数范围内做任何随机的操作,随 ...
- Application_Error VS OnException 遇到的坑
在工作中遇到一个巨坑,就是关于Application_Error和OnException, 本身我的应用程序设置了全局异常OnException处理,手动抛出异常,OnExcep ...
- vs2010/2013项目的C++所在文件夹越来越大如何解决?
vs2010/2013项目所在文件夹越来越大如何解决? Tools->Options->Text Editor->C/C++->Advanced,在 Fallback Loca ...
- linux 监测函数
http://www.ttlsa.com/linux/the-nethogs-view-each-process-uses-bandwidth/ Linux的IO性能监控工具iostat详解 http ...
- ios - block循环引用Demo示例
当实例变量中有了block属性,并且用copy来修饰,但是当调用block中的代码的时候,如果block中运用了self.属性的时候回造成循环引用. // // ViewController.h // ...
- Linux selinux iptables
关闭SELINUX – 使用getenforce命令检查SELINUX状态,若结果不是”Disabled”,可使用setenforce 0命令临时关闭SELINUX.要永久关闭SELINUX,需修改/ ...