- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑以下语句:
int *pFarr, *pVarr;
int farr[3] = {11,22,33};
int varr[3] = {7,8,9};
pFarr = &(farr[0]);
pVarr = varr;
在这个阶段,两个指针都指向每个相应数组地址的开头。对于 *pFarr,我们目前正在寻找 11,对于 *pVarr,我们目前正在寻找 7。
同样,如果我通过*farr 和*varr 请求每个数组的内容,我也得到11 和7。
到目前为止一切顺利。
现在,让我们试试 pFarr++
和 pVarr++
。伟大的。正如预期的那样,我们现在正在查看 22 和 8。
但是现在...
试图向上移动 farr++
和 varr++
......我们得到“错误的递增参数类型”。
现在,我认识到数组指针和常规指针之间的区别,但由于它们的行为相似,为什么会有这种限制?
当我还考虑到在同一个程序中我可以以一种表面上正确的方式和另一种不正确的方式调用以下函数时,这让我更加困惑,而且我得到了相同的行为,尽管与代码贴在上面!?
working_on_pointers ( pFarr, farr ); // calling with expected parameters
working_on_pointers ( farr, pFarr ); // calling with inverted parameters
.
void working_on_pointers ( int *pExpect, int aExpect[] ) {
printf("%i", *pExpect); // displays the contents of pExpect ok
printf("%i", *aExpect); // displays the contents of aExpect ok
pExpect++; // no warnings or errors
aExpect++; // no warnings or errors
printf("%i", *pExpect); // displays the next element or an overflow element (with no errors)
printf("%i", *aExpect); // displays the next element or an overflow element (with no errors)
}
谁能帮我理解为什么数组指针和指针在某些上下文中的行为相似,而在其他上下文中却不同?
非常感谢。
编辑:像我这样的菜鸟可以从这个资源中进一步受益: http://www.panix.com/~elflord/cpp/gotchas/index.shtml
最佳答案
不同之处在于,要使 farr++
生效,编译器需要在某处存储 farr
将计算为数组第二个元素的地址。但是没有地方存放这些信息。编译器只为 3
整数分配位置。
现在当你声明一个函数参数是一个数组时,函数参数将不是一个数组。函数参数将是一个指针。 C中没有数组参数,所以下面两个声明是等价的
void f(int *a);
void f(int a[]);
括号中的数字是多少并不重要 - 因为参数实际上是一个指针,所以“大小”将被忽略。
这对于函数也是一样的——下面两个是等价的,并且有一个函数指针作为参数:
void f(void (*p)());
void f(void p());
虽然您可以同时调用函数指针和函数(因此它们的用法相似),但您也不能写入函数,因为它不是指针 - 它只是转换 指向一个指针:
f = NULL; // error!
与您无法修改数组的方式大致相同。
关于c - 指针运算和数组 : what's really legal?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2383837/
我经常听到有人这样说 All JavaScript code is legal TypeScript code 或 TypeScript is a superset of JavaScript 但是当
如果为对象预留内存(例如,通过 union )但构造函数尚未被调用,调用对象的非静态方法之一是否合法,假设该方法不依赖于值任何成员变量? 我做了一些研究,发现了一些关于“变体成员”的信息,但找不到与此
更新! 请参阅下面我对 C# 规范的一部分的剖析;我想我一定遗漏了什么,因为对我来说,我在这个问题中描述的行为实际上违反了规范。 更新2! 好的,经过进一步思考,并根据一些评论,我想我现在明白发生了什
我有代码: #include template class> struct Foo { enum { n = 77 }; }; template class C> struct Foo {
int ar[] = { 1, 2, 3, }; 这段代码合法吗? (我的意图是) int ar[] = { 1, 2, 3 }; 最佳答案 是的,C89 和 GNU89 中的初始化列表中都允许使用杂
我有一个 map View 被以下代码剪裁成一个圆圈。 roundMapView.layer.cornerRadius = roundMapView.frame.size.width/2
这个问题已经存在: Why sizeof(x++) does not increment the variable x value [duplicate] 关闭 9 年前。 给定以下代码,它在 C
在深入研究 MFC 时,我发现了这段代码: _AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const { return this == NULL ? NULL
我正在使用 MKMapSnapshotter 创建一个小型 MKMapView 的 UIImage 屏幕截图(并存储以备后用)。但我注意到的一件事是它从快照中删除了“合法”标签。 Here答案是删除“
在这个公认的人为设计的示例中,X 类型的右值在语句末尾按预期被销毁。但是,被销毁的对象仍然可以通过非常量引用“x”访问。这是合法的 C++ 吗?如果是这样,结果是未定义的还是未指定的?编译器不应该在这
这是一段显然不起作用的代码,因为在构造函数中向下转换“this”是非法的: #include class A { protected: virtual ~A() {} public:
考虑以下语句: int *pFarr, *pVarr; int farr[3] = {11,22,33}; int varr[3] = {7,8,9}; pFarr = &(farr
似乎只有向上滑动才能移除带动画的导航栏。我想让它褪色,就像在 Photos.app 中一样。 更改 alpha 最简单,但是 Apple's guidelines state : Prior to i
考虑一下这个相当无用的程序: #include int main(int argc, char* argv[]) { int a = 5; auto it = [&](auto self)
我添加了一个 MKMapView作为 XIB 中我的一个 ViewController 的 subview 。该 map 在显示方向方面工作正常。但是 Legal map 上的文字(左下)显示为 而不
这个问题在这里已经有了答案: JavaScript ternary operator example with functions (6 个答案) Ternary operators in Java
我有两个类如下。 class NeuroShield { public: NeuroShield(); uint16_t begin(); void setNcr(uint16
能够将传递给文字运算符的字符串转换为 MPL 序列会很有用,因为这样我们就可以根据字符串的内容控制代码生成。以前,我认为这是不可能的,因为 constexpr 函数的参数在函数体内不被视为常量表达式。
这是一个有点深奥的问题,但我很好奇以下类扩展模式在现代 C++ 中是否合法(例如,不构成 UB)(出于所有意图和目的,我可以将讨论限制在 C+ +17 及更高版本)。 template struct
我正在使用 MagicalRecord, 这就是我设置 coreData 堆栈的方式 - (BOOL)application:(UIApplication *)application didFinis
我是一名优秀的程序员,十分优秀!