和指针相关的问题口诀1

1. 地址变量得地址,得谁地址指向谁

和指针相关的问题要画图: 内容变量画房子,指针画箭头

---->口

----------------------------------------------------

和指针相关的两个特殊运算符:

一、"&" 取地址运算符,通过&运算符可以取出普通变量的地址;

二、"*"  有两种意义:

1.  为指针标志: 是否为指针标志主要看前面是否有类型,此处有一个int

2.  为指针运算符:

     在等号右面为取值。*可以取出指针变量所指向的普通变量的值。

     在等号左面为赋值。*可以将指针变量所指向的普通变量的值,修改为其他。

口诀2有* 为内容值,不是读就是写。等号左面为赋值, 其余都为取值。

3.  为乘法运算符。当且仅当左右的都为变量时。略。

int a, b =20, c=30, d=40, *p; (正确,此处的*为指针标志,只起到定义的左右,没有取值和赋值的作用。是否为指针标志主要看前面是否有类型,此处最前面有一个int)

p=&d; (正确,p指向d的地址)

a=*p;  (正确,此处的*为取值。最后结果a的值变为了d的值40)

*p =c; (正确,此处的*为赋值。最后结果d的值变为了C的值30)

*p =&b; (运行错误,左边为内容值,右边为地址,不等价)

--------------------------------------------------------

和指针相关的等价表达式

若指针变量p指向变量a,即将变量a的地址赋给了指针变量p.

如:int a=20, int *p=&a;

则有如下结果:

A、*p <=> a

B、 p <=> &a

C、 &*p <=> &a <=> p

D、*&a <=> *p <=> a

E、 (*p)++  a++

(*p)--  a--

++(*p)  ++a   ++*p

--(*p)  --a   --*p

可以看出 * 和 & 是互逆的两个运算符

--------------------------------------------------------

所有的指针变量在内存中分配的字节数相同 sizeof(指针) 永远是 两个字节, 不管指针定义时是 int *, float * 还是 double * . 详细如下

int *p1;   则 p1以后必须指向int 类型的变量。   但指针本身的长度,sizeof(p1) 为2个字节(2*8bit -16bit)

float *p2;   则 p2以后必须指向float 类型的变量。   但指针本身的长度,sizeof(p2) 为2个字节(2*8bit -16bit)

double *p3;   则 p3以后必须指向double 类型的变量。   但指针本身的长度,sizeof(p3) 为2个字节(2*8bit -16bit)

-----------------------------------------------------------

四道例题:

例子1.

void fun (int *x , int *y) {
  printf("%d, %d", *x, *y) ;
  *x = 3;
  *y = 4;
}

main()
{
int x = 1, y = 2
fun(&y, &x);
printf("%d, %d", x, y);
}

结果
2, 1
4, 3

注意main在调用fun函数时, y 和x故意写颠倒了。

--------------------------------------------------------------

例子2.

#include <stdio.h>
void swap(int *p1, int *p2)
{
int temp;
temp = *p1;
*p1 = *p2;
*p2 = temp;
}

main()
{
int a, b;
int * p1 = &a, *p2 = &b;
scanf(%d %d, p1, p2);
swap(p1, p2);
prinf("%d, %d", *p1, *p2);
}

如果在控制台输入  2 和 5

则输出结果为

5, 2

原因: 在调用swap函数时使用了职称,所以在swap函数内部对p1,p2 所引用的内容值的修改,会影响外面的a和b的值。

--------------------------------------------------------------

例子3:

#include <stdio.h>
void swap(int *p1, int *p2)
{
int *temp;
temp = p1;
p1 = p2;
p2 = temp;
}

main()
{
int a, b;
int * p1 = &a, *p2 = &b;
scanf(%d %d, p1, p2);
swap(p1, p2);
prinf("%d, %d", *p1, *p2);
}

和2不同, swap函数中的temp为指针,temp=p1使得temp指向了2,p1=p2使得p1指向了5,p2=temp使得p2指向了5.

但最后的打印结果仍为
2,5

原因是:虽然main中调用swap函数时使用了指针传递,但swap函数中的所有操作都是:将指针本身的修改,而没有再次使用*操作符来修改“指针指向的内容值”

口诀3:没有*的指针操作为地址,地址的赋值意味着改指向。

---------------------------------------------------------------------

例子4:

#include <stdio.h>
void swap(int *p1, int *p2)
{
int *temp;
*temp = *p1;
*p1 = *p2;
*p2 = *temp;
}

main()
{
int a, b;
int * p1 = &a, *p2 = &b;
scanf(%d %d, p1, p2);
swap(p1, p2);
prinf("%d, %d", *p1, *p2);
}

和2很像。但唯一不同是,temp定义为指针而不是普通变量。看上去似乎应该和2的输出结果一样,仍为
2,5 。

但实际运行时编译器会报错:非法的内存写入。

原因是:temp为野指针,并没有预订指向哪里。如果指向系统区,则可能导致操作系统死机或崩溃。

如果temp在定义后,马上给一个初始值,就不会有问题了。

---------------------------------------------------------------------

指针、数组的等价符号

若将数组作为形参,则将数组名作为指针变量来处理。

int fun(int a[10]) <=> int fun(int *a) <=> int fun(int a[])

可以看出,口诀4:  &与*互逆。 *与[]等价, &与[]互逆

例子5:

int s[10], a, b;
in d[3][6];

int *p;
p=&a; //p 指向了整数a
p = &s[2]; //p指向了s数组的第二个元素
p= &d[2][4];p指向了d数组的第二行、第四列的元素。

所以,以上的语句都是对的。

上面的例子:

1. 定义了一个int s[10];   则 s等同于 &s[0].   即,看到一个数组,就马上联想到他代表的是数组第一个元素的地址。

在C语言中规定,数据名代表数组的首地址,并且是一个地址常量

2. 另外,如果定义了一个指针 int *ppp = s;  则   ppp 定价于s,  同时等价于 &s[0]。

---------------------------------------------------------------------

指针的加减:

当指针变量指向数组中的某一个地址时,指针变量加1后指向数组的下一个元素,
指针变量减1时指向数组的前一个元素。

例子6:

float a[10]; float *p;
p=&a[4]; 则p-3指向?

先画图:

a[0] | a[1] | a[2] | a[3] | a[4] | ...

p的初始位置指向了 a[4],  则 p-3 为向前3个,指向了 a[1]

口诀5:  指针的加减是向前或向后移动了n个元素

---------------------------------------------------------------------

int a[N], *p=a;

则有:

地址三等价:

存在等价表达式:

p+i <=> a+i <=> &a[i]  代表的是第i个元素的地址

元素四等价:

存在等价表达式:

1.   *(p+i) <=> *(a+i) <=> a[i]   代表的是第i个元素的值

2.  另外,还有 p[i] <=> a[i] 。 p[i] 的用法不多见,但无任何错误,代表的也是第i个元素的值。原因是p和a完全等价。

整理出来的等价式如下:

a) *(p+i) <=> *(a+i) <=> a[i] <=> p[i]
b) p++ <=> ++p <=>  p+=1 <=>  p=p+1
c) p-- <=>  --p  <=>  p-=1  <=>  p=p-1
d) *p++  <=>   *(p++)
   说明:* 与 ++ 的运算优先级一样,所以按照从右到左的结合原则,先执行++,后执行*
   ++在p的后面,为执行后再加。即先把p的值取出,指针再加1.
e) *++p  <=>  *(++p)
    ++在p的前面,为先加再执行。即先把指针加1, 再把移动后的p所指向的值取出,
f) (*p)++ <=>   ++(*p)  <=>   ++*p
    将p的内容自增
g) (*p)--  <=>  --(*p)  <=>   --*p
    将p的内容自减

C语言之指针与数组总结相关推荐

  1. 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  2. c语言常量l12和意义,课件c语言l12_指针和数组

    <课件c语言l12_指针和数组>由会员分享,可在线阅读,更多相关<课件c语言l12_指针和数组(42页珍藏版)>请在人人文库网上搜索. 1.计算机程序设计基础第12讲指针和数组 ...

  3. C语言 使用指针遍历数组 - C语言零基础入门教程

    目录 一.使用数组下标遍历数组 1.计算数组元素个数 2.通过下标遍历数组 二.使用数组首地址偏移遍历数组 三.使用指针遍历数组 四.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目 ...

  4. c语言指针数组 难点总结,C语言之指针与数组总结

    和指针相关的问题口诀1: 1. 地址变量得地址,得谁地址指向谁 和指针相关的问题要画图: 内容变量画房子,指针画箭头 ---->口 ------------------------------- ...

  5. C语言中指针与数组的区别,C语言 指针与数组的详解及区别

    C语言 指针与数组的详解及对比 通俗理解数组指针和指针数组 数组指针: eg:int( *arr)[10]; 数组指针通俗理解就是这个数组作为指针,指向某一个变量. 指针数组: eg:int*arr[ ...

  6. 国2c语言中指针与数组的赋值运算,C语言到汇编-指针与数组2

    本章剩下的内容主要有: 1.指针与数组 & 地址算术运算 2.字符指针与函数 3.多维数组 & 指针与多维数组 4.指向函数的指针 每个内容举一个例子,第一个例子: int a[10] ...

  7. 水滴石穿C语言之指针、数组和函数

    基本解释 1.指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址):数组的本质则是一系列的变量. 2.数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容 ...

  8. C语言中指针和数组的区别

    看<C专家编程>一书,看到数组与指针并不相同一章,遂做了一段测试: 代码: #include <stdio.h> #include <stdlib.h>int ma ...

  9. c语言,指针与数组--指针与二维数组2

    指向一维数组的指针   char (*p)[10] ; 指向一维数组的指针类型 typedef  char(*TYPE_P2ARRAY)[10]  ;    该指针可以指向数组 ,且使用起来效果节本相 ...

最新文章

  1. 《2019人工智能发展报告》!含计算机视觉、机器人等13个子领域(附链接)
  2. 第十六节:语法总结(3)(C#6.0和C#7.0新语法)
  3. iOS 中 OC项目使用swift第三方工具(OC、swift 混合)
  4. 磁盘镜像工具Guymager
  5. IDEA 引入传统 j2ee spring mvc
  6. JQuery.Ajax()的data参数传递方式
  7. Docker实战:Docker安装部署RabbitMQ
  8. 程序猿的英语之ielts indicator speaking test
  9. 使用httpHandlers进行url rewrite时,提示http 404 error 错误
  10. SpringCloud局部过滤器自定义
  11. 1.5 编程基础之循环控制 45 金币 方法二(python3实现)
  12. 基于JAVA+SpringMVC+Mybatis+MYSQL的酒店客房管理系统
  13. 接入TapTap防沉迷系统的逻辑图
  14. python用pyecharts画柱状图_小白学Python(13)——pyecharts 绘制 柱状图/条形图 Bar
  15. php 数字转换为货币,php中数字转换成货币格式实现代码
  16. java 多次正则匹配_Java正则多次匹配和多次组匹配
  17. Windows组策略禁止广告弹窗
  18. 让你相见恨晚的Photoshop 技巧
  19. 利用MATLAB进行shp文件转换并绘制断层线
  20. 解决“error C1083: 无法打开包括文件: “HPSocket.h”: No such file or directory”

热门文章

  1. yunos5 linux内核,魅蓝5S、魅蓝5对比看差异 选Android还是YunOS?
  2. kali linux之edb--CrossFire缓冲区溢出
  3. maven系列一:pom.xml文件详解
  4. 网站如何接入第三方登录,微信登录和QQ登录:注册认证篇
  5. 数据库 oracle 设计三范式
  6. bzoj 36733674 可持久化并查集加强版(可持久化线段树+启发式合并)
  7. mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法
  8. 深入浅出Nintex——更新PeopleandGroup类型的Field
  9. 安卓APP_ Fragment(3)—— Fragment的生命周期
  10. 安卓APP_ 布局(7) —— ViewPager翻页