1. 指针与数组

c语言中的数组要注意以下两点:

下面的方法存在问题,因为数组的大小必须在编译期作为一个常数确定下来。

a[3][4] 本质也是一个一维数组(包含3个元素),只不过一维数组中的元素是也是数组(包含4个元素)。

int  ar[10] = { 0 }; 注意:数组名代表的是整个数组空间。由sizeof(ar)=40  可以体现。

三者的内容相同,但解释是不同的。

&a[0] 针对首个元素取地址。

ar 数组名包含的内容,恰好是数组首元素的地址。但是数组名和数组首元素的地址不能划为等号。

&ar  数组空间的地址

&ar[0] 和ar都是普通的整型指针

这里要明白,&ar实际类型是数组指针

二维数组 (实际没有二维数组,只是一维数组的元素还为数组)

对于二维数组而言,数组名同样表示数组首元素的地址,而ar的首元素还是个

数组,因此,对应的指针也应该是数组指针。

二维数组, int ar[3][4];
ar实质上是一个指针的指针, 即二级指针。
一个指针加一个数, 当然还是指针(即a+1是指针)
取值一个二级指针, 是一级指针(即指针), 所以还是指针, 不过类型发生了变化.
a+1的类型为int * [4].
而*(a+1)的类型则为int *, 也就是平常的指针。

因此,为二维 数组中某一元素赋值用*(*(ar+1)+1)= 100.

2. 非数组的指针

r为指针 即地址。

想往r中拷贝 就需要为r开辟空间。

malloc开辟的空间是10,后面的\0没有空间存储。此时不会报错的

原因是恰好第11个位置没有被占用,如果被占用了就会报错。

为了避免上述问题,开辟的空间加1.

char *r = (char *)malloc(strlen(s)+strlen(t)+1)

同理,要想往 char *name中拷贝就需要为name开辟空间

3. 作为参数的数组声明

(1)

a和b中的值均为数组首元素的地址

int a[5] = {1,2,3,4,5};

printf("%p",a); //打印出的是a的地址

由于整型数组没有结束标记,打印时 只能把a当做地址来打印。

char b[ ] = "hello";

printf(b);   //打印出的是字符串 hello

原因:字符数组和字符指针可通过首地址输出整个数组,整形数组却不可以。原因分析如下:
String是一个类,会重载toString()函数,toString()返回其本身。所以直接输出String类的对象会输出具体字符串。而字符型数组在内存中的储存方式同String类一样,因此输出数组名并非输出数组首地址,而是直接输出数组内容直到/0;而整形数组只是整形的集合,所以其数组名仅仅是其首地址,需用for循环输出整个整形数组。

举例:

值分别为40和4

说明数组名和数组首元素地址并不能划为等号,只是数组名的值是首元素地址。

因此不能对数组进行整体赋值。即br = ar不可取。

两个fun函数等价。

在调用函数fun(br)时,表面上看起来像传输的是整个br数组,实际传输的是br的首地址

因此注意,如果函数的参数是以数组的形式传递,那么,数组形式要退化为指针。

4. 避免举偶法陷阱

混淆指针与指针所指向的数据。

*p空间存储的并不是hello字符串

系统会开辟两个空间,一是为hello开辟的静态常量空间  其实位置是0x0042201c

二是为指针变量*p在栈区开辟的空间0x0013ff7c。而空间0x0013ff7c存储的是hello空间的首地址0x0042201c。

陷阱一:以下两种操作,字符串的存储方式不同。

char *p = “hello”;

p[0] =‘H’; 程序会崩溃,原因是不允许修改 静态常量空间中的 字符串常量。

而char p[ ] = "hello";

p[0] = 'H';   则没问题,p[]是数组空间,会在栈区开辟空间,在栈区修改数组的内容是完全可以的。

陷阱二:

char *p = "hello";

char *q = p;

此时,p和q对应的栈区空间地址不同,但是这两个地址中存放的内容是相同的,都是hello的存储空间的首地址,即两个指针指向同一个地址。

陷阱三:

此时,不能重复释放空间。

5. 空指针并非空字符串

char *p = NULL; //p没有任何指向

char *q ="";   //q指向的内容为\0

6. 边界计算与不对称边界

数组 左闭右开  栈的生长方向是从高地址到低地址。

图中,内存上边是低地址 下面是高地址,所以i在高地址 a在低地址

如上程序会一直循环,

原因是:在内存中,a[10]的位置恰好为i,a[10]相当于对i赋值,这会导致i的值一直小于10。

栈:它的生长方式是向下的,是向着内存地址减小的方向增长。栈的开口是向下的,上面的底部是栈底,下面的开口是栈顶。

缓冲区设计

7. 求值顺序陷阱

短路求值

8. 运算符&& ||  !  按位 & | ~(取反)

逻辑运算的结果只能是真或假

c缺陷与陷阱 第3章 语义陷阱相关推荐

  1. 《C陷阱与缺陷》----第三章 语义陷阱

    第三章. 语义陷阱 3.1 指针与数组 3.2 非数组的指针 3.3 作为参数的数组声明 3.4 空指针并非空字符串 3.5 边界计算与不对称边界 3.6 求值顺序 3.9 整数溢出 3.10 为函数 ...

  2. 《C陷阱与缺陷》一第1章 词法“陷阱”1.1 =不同于==

    本节书摘来自异步社区<C陷阱与缺陷>一书中的第1章,第1.1节,作者 [美]Andrew Koenig,更多章节内容可以访问云栖社区"异步社区"公众号查看 第1章 词法 ...

  3. C陷阱与缺陷 第3章 语义“陷阱” 3.4 避免“举偶法”

    避免"举偶法"     "举偶法"(synecdoche)是一种文学修辞上的手段,有点类似于以微笑表示喜悦.赞许之情,或以隐喻表示指代物与被指代物的相互关系.在 ...

  4. 《C陷阱与缺陷》----第二章 语法陷阱

    第二章 语法陷阱 2.1 理解函数声明 2.1.1 如何理解函数声明 2.1.2 举例理解声明 2.1.2.1 例子1 2.1.2.2 例子2 2.2 运算符的优先级 2.2.1 常见错例 2.2.1 ...

  5. 《C陷阱与缺陷》——第三章(语义陷阱)

    文章目录 一.指针与数组 二.非数组指针 三.作为参数的数组声明 四.避免"举隅法" 五.空指针并非空字符串 六.边界计算与不对称边界 七.求值顺序 八.运算符&& ...

  6. C陷阱与缺陷代码分析之第2章语法陷阱

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 陷阱1 理解函数声明 作者提出一个问题:有一个首地址为0的函数,该函数返回值类型为void,没有参数.怎样用C语言的 ...

  7. C陷阱与缺陷--读书笔记3 语义“陷阱”

    第三章 一.知识点 1.C语言中的数组值得注意的地方有以下两点:(P41) (1).C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来.然而,C语言中数组的元素可以是任何类型的对象 ...

  8. 【C缺陷与陷阱】----语义“陷阱”

  9. C陷阱与缺陷 第2章 语法“陷阱” 2.6 “悬挂”else引发的问题

    "悬挂"else引发的问题     if (x == 0)      if (y == 0) error();     else {         z = x + y;     ...

最新文章

  1. 揭秘PHP深受Web开发者喜爱的原因
  2. netbeans html 格式化,在NetBeans IDE8.0中怎么把html的文件转换成jsp格式
  3. iphone-common-codes-ccteam源代码 CCTestMacros.m
  4. 译 | 将数据从Cosmos DB迁移到本地JSON文件
  5. 【LeetCode笔记】剑指 Offer 58 - I. 翻转单词顺序(Java、栈、双指针)
  6. linux用pe大小做逻辑卷,Linux常用命令之--逻辑卷
  7. mysql存储登录密码_用户身份验证:存储用户ID和密码在一个MySQL数据库
  8. 《数据库实验》实验一:建立数据库和基本表结构
  9. U盘修复,U盘量产教程(以台电晶彩NCU,容量为32G的U盘为实例)by aser
  10. DDOS专题详细讲解
  11. MySql 查询语句替换换行符
  12. HTML径向效果,HTML5版径向渐变梯度色彩
  13. 【云和恩墨大讲堂】高凯 | Oracle 12c 新特性-多租户的维护管理
  14. 大白菜装机教程win10_win10安装教程
  15. end kernel panic not syncing
  16. 杰理之探测芯片最高稳定运行频率【篇】
  17. 2011 Esri中国开发者大会
  18. ANSYS流固耦合仿真总结
  19. 基于Python的江苏大学校园网暴力破解
  20. 自己制作本地yum源镜像

热门文章

  1. dock接口_手机统一充电接口,苹果反对无效,安卓手机的充电器接口早已统一...
  2. Substance Painter - Blender - UE4/5 低模 高模 烘焙 ID 流程
  3. 开放API接口 练习学习接口
  4. 数字孪生智慧城市运用于三维可视化管理系统
  5. java键入时间hhmm_日期-SimpleDateFormat上的Java HH:mm和hh:mm之间的差异
  6. 总结2019,规划2020,未完待续
  7. 说话人识别神经网络推理方式
  8. 为什么商务人都申请163邮箱,163邮箱怎么注册登陆呢?
  9. 服务器压缩PNG图片
  10. 如何以Java实现网页截图技术