瘋子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)能力,记录 ...
随机推荐
- iOS索引列开发详解
做苹果开发的朋友在地区列表可能会遇到在页面的右侧有一列类似与导航的索引列,这次有机会遇到了,细细研究了一下,原来没有想象中的困难,只需要简单的几步就能做出自己的索引列.本来想和搜索条在一块讲解,后来考 ...
- SQLite XXTea加密学习
这几天优化数据库读写,移植了xxtea加密到最新的数据库sqlite 3.12.2里,一些好文章放在这里.移植后,数据库读写性能异常优秀! 这几天又发现,数据库还是发生了无法写入情况,数据库崩溃掉了. ...
- phpstudy的apache端口没有被占用,也有vc9,防火墙也没开,也开杀毒软件,就是无法启动apache
我电脑装了一个独立的apche和一个phpstudy的apache,我学习是教学视频是php5.2而phpstudy刚好支持. 但是我在选取phpstudy的php版本5.3n以上就无法启动apach ...
- 使用JCIFS获取远程共享文件
package com.jadyer.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOExc ...
- Java提高篇——理解String 及 String.intern() 在实际中的应用
1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ...
- react 调用 native 的callShareAllFunc()方法,实现分享
let shareName = { '0': '微信', '1': '朋友圈', '2': '新浪微博', '3': ' QQ', '4': 'QQ空间'};render(){ //分享YztApp. ...
- vue.js在windows本地下搭建环境和创建项目
Vue.js是一套构建用户界面的渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合.另一方面,Vu ...
- PHP部分资料
完善PHP登陆注册页面,同时连接mysql数据库 http://blog.csdn.net/tianlu1677/article/details/7765889/ PHP 附录 : 用户注册与登录完整 ...
- 使用IIS发布WCF服务
上一篇是Windows服务为宿主的WCF服务,现在用IIS为宿主发布WCF服务. 第一步:肯定是新建一个WCF服务啦[是WCF服务应用程序],然后在解决方案上再次添加一个新项目[我们选择WCF服务库, ...
- Fiddler的一些坑: !SecureClientPipeDirect failed: System.IO.IOException
手机的请求Fiddler可以捕捉,但是手机一直无法上网,在logs中看到的日志如下: !SecureClientPipeDirect failed: System.IO.IOException 由于远 ...