C指针陷阱
问题一:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[]={
,,,,
};
int *p =(int *)(&a+);
printf("%d,%d\n",*(a+),*(p-));
return ;
}
答案结果:2,5
解析:a 和&a的地址一样,但是意思不一样,a是数组的首地址,也就是a[0]的地址;
&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],而&a+1是下一个对象的地址,即a[5]。
所以:p实际上是a[5]的地址,但是p本身是指向int类型数据的指针,所以p-1只会减去sizeof(int*)。
注意:p=&a这样写法在ANSI C中是非法的,因为&a是一个指向数组的指针,而p是一个指向整形变量的指针,他们类型不匹配
问题二:
二维数组那点事:二维数组在内存中占据连续的空间,在内存中从上到下存储各行元素,在同一行中按照从左到右的顺序存储,因此我们可以根据行号和列好
来计算出相对于数组首地址的偏移量,从而找到对应的元组,比如:arr[row*columns+column]
问题三:
1, 以指针类型出现:
C语言中,指针类型值的本质为地址。
C语言规定,不同类型的指针,不可以做相减操作,只有同类才可以进行减操作。比如同样是char*,或者同样是int*等。注意int *和int**,即一维指针和二维指针属于不同类型。
同类型相减的计算原则为
T *a, *b;
a-b=(a与b值的算术差值)/sizeof(T);
2, 以整型变量形式。比如将地址值转为long型存储,这时地址本身已经转换成了一个整型变量,所以相减结果就是值的算术差。
3,两个Int型变量的地址之差就是这两个地址中间可以有多少个int型变量。(这是因为C语言可以根据变量的类型来决定地址增加的实际空间。比如你定义一个int指针int*p,
p=p+1时,其实在内存地址中实际加4,因为int在C中4个字节。)
C指针陷阱的更多相关文章
- 必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱
必须要注意的 C++ 动态内存资源管理(五)——智能指针陷阱 十三.小心使用智能指针. 在前面几节已经很详细了介绍了智能指针适用方式.看起来,似乎智能指针很强大,能够很方便很安全的管理 ...
- 【C++】智能指针详解
转自:https://blog.csdn.net/flowing_wind/article/details/81301001 参考资料:<C++ Primer中文版 第五版>我们知道除了静 ...
- [转载] C++ typedef 用法详解
typedef的语法描述 在现实生活中,信息的概念可能是长度,数量和面积等.在C语言中,信息被抽象为int.float和 double等基本数据类型.从基本数据类型名称上,不能够看出其所代表的物理属性 ...
- Go学习笔记01-语言
1.1 变量 Go 是静态类型语言,不能在运行期改变变量类型.使用关键字 var 定义变量,自动初始化为零值.如果提供初始化值,可省略变量类型,由编译器自动推断. var x int var f fl ...
- 问题:这个新申请的内存为什么不能free掉?(已解决)
一.问题描述 先上代码, /*** 省略 ***/ uChar *base64 = NULL; /*** 省略 ***/ base64 = (一段内存) /*** 省略 ***/ base64 = s ...
- [C++ Primer] : 第12章: 动态内存
动态内存与只能指针 静态内存用来保存局部static对象, 类static数据成员以及定义在任何函数之外的变量. 栈内存用来保存定义在函数内的非static对象. 分配在静态或栈内存中的对象由编译器自 ...
- typedef用法和与define的区别
typedef用来声明一个别名,typedef后面的语法,是一个声明.本来笔者以为这里不会产生什么误解的,但结果却出乎意料,产生误解的人不在少数.罪魁祸首又是那些害人的教材.在这些教材中介绍typed ...
- #define与typedef
#define(宏定义)只是简单的字符串代换(原地扩展),它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了. typedef是为了增加可读性而为标识符另起的新名称(仅仅只是个别名), ...
- C++基础之动态内存
C++支持动态分配对象,它的生命周期与它们在哪里创建无关,只有当显示的被释放时,这些对象才会被销毁.分配在静态或栈内存中的对象由编译器自动创建和销毁. new在动态内存中为对象分配空间并返回一个指向该 ...
随机推荐
- C++可变参数的另一种实现
大家熟知的C库函数printf函数就是一个可变参数函数,它是怎么实现的呢?不过他实现是有条件的,必须函数参数的入栈顺序为从右向左的顺序,也即函数的形参,在函数调用之前,必须是最右边的参数先入栈,并且参 ...
- mysql 函数执行权限
mysql> show grants for query_all@'115.236.1x0.x'; +---------------------------------------------- ...
- oracle rman异机恢复
Oracle源主机 Oracle目标主机 主机平台 CentOS6.2(final) CentOs6.2(FInal) 主机名 vick rman IP地址 192.168.1.11 192.16 ...
- 对JAVA Bean使用PropertyDescriptor反射调用JAVA方法
对于符合JAVA Bean规范的bean,调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性. 示比例如以下: NonCo ...
- 使用命令行将Excel数据表导入Mysql中的方法小结
从Excel数据表导入MySQL,已经做过好几次了,但每次都会碰到各种问题:invalid utf8 character string, data too long, ...,浪费了不少时间 为了提高 ...
- 零行代码为App添加异常加载占位图
前文提要 近期准备重构项目,需要重写一些通用模块,正巧需要设置App异常加载占位图的问题,心血来潮设想是否可以零行代码解决此问题,特在此分享实现思路. 思路分享 对于App占位图,通常需要考虑的控件有 ...
- 在Mac pro上如何配置adb命令?
在Mac pro上如何将Android SDK的adb命令添加到环境变量中,这里将进行说明! 方法/步骤 1 启动终端,可以在Spotlight中搜索“终端” 2 进入当前用户的HOME目录,命令如下 ...
- 【Java】 实现一个简单文件浏览器(2)
接着上篇文章 接下来说下程序右侧的文件内容表格如何实现 FileTable类: FileTable基础于JTable类,构造函数里用setDefaultRenderer设置每行默认的渲染器为FileT ...
- shell学习-读取输入
功能:读取输入,打印:如果长度小于MINLEN,那么输出空格. #!/bin/bash # paragraph-space.sh # Insert a blank line between parag ...
- selenium 学习笔记 ---新手学习记录(4) 问题总结(java)-autoit3脚本使用
1.安装autoit3 下载地址:点我下载 (提取码:9633) 提取码 下载完成后,一直下一步即可 2.上传头像使用脚本 代码如下: ControlFocus("打开",&quo ...