当前位置: 首页 > news >正文

瘋子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型的指针的函数
int(*p)();函数指针)p为指向函数的指针,该函数返回一个整型值
int **p;p是一个指针变量,它指向一个指向整型数据的指针变量

 例:

nt(*p)();是一个函数指针

 

int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。

一个数组全是函数指针;

(uint32_t *)(x)  等价于 uint32_t (*p)(x) p代表函数指针,对该地址的存储量操作,如下:

(*((volatile uint32_t *)(x)))

取该地址的量;

 

 

 

 

 也就是括进去的是指针,没有括进去的是数组或函数;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

                                                              下次更新时间2014.10.10

                                                              新的理解和见解可留言相互交流,共同学习  

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Ph-one/p/3963737.html

相关文章:

  • keil_4/MDK各种数据类型占用的字节数
  • 汽车OBD接口定义
  • CAN/J1850/
  • STM32.BOOT
  • DMA(STM32)
  • STM32.printf
  • STM32各个文件介绍、uCOSII文件介绍
  • Cortex-M3基础
  • Program Size
  • KEIL中常见问题
  • LM2596、LM2576
  • STM32硬件IIC
  • CP2102
  • SMBus
  • 0x30、0x37
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • const let
  • Go 语言编译器的 //go: 详解
  • go语言学习初探(一)
  • Javascript 原型链
  • JavaScript创建对象的四种方式
  • leetcode98. Validate Binary Search Tree
  • mockjs让前端开发独立于后端
  • PHP 7 修改了什么呢 -- 2
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • uni-app项目数字滚动
  • 工作中总结前端开发流程--vue项目
  • 猴子数据域名防封接口降低小说被封的风险
  • 将回调地狱按在地上摩擦的Promise
  • 讲清楚之javascript作用域
  • 如何使用 JavaScript 解析 URL
  • 设计模式 开闭原则
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 我感觉这是史上最牛的防sql注入方法类
  • elasticsearch-head插件安装
  • 数据可视化之下发图实践
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • # 计算机视觉入门
  • #laravel 通过手动安装依赖PHPExcel#
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (原創) 未来三学期想要修的课 (日記)
  • (转)ObjectiveC 深浅拷贝学习
  • (转)菜鸟学数据库(三)——存储过程
  • (转)我也是一只IT小小鸟
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .Net Web窗口页属性
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET简谈设计模式之(单件模式)
  • .NET企业级应用架构设计系列之开场白
  • .NET中两种OCR方式对比
  • [AIGC 大数据基础]hive浅谈
  • [C/C++]数据结构 栈和队列()