关于C/C+指针的5个问题

本文总结了*网站上关于C/C+指针的主要问题。指针是C/C+中最令人困惑的部分,这些问题使用简单的例子来解释关键指针的概念。

 

1.不使用循环从1计数到1000

 

#include <stdio.h>#include <stdlib.h> void main(int j) {
 printf("%d\n", j);
 (&main + (&exit - &main)*(j/1000))(j+1);}

 

计数1到1000的唯一其他方法是使用递归。根据C语言,j在开头以‘1’作为它的值。当1<=j<1000时,&main+(&Exit-&main)*(j/1000)总是求值为&main,这是main的内存地址。

 

(&main)(j+1)是我们想要得到的下一个迭代,它会在屏幕上打印‘2’等等。此递归的停止条件是,当j点击1000时,&main+(&Exit-&main)*(j/1000)的计算结果为&Exit,这将优雅地退出该进程,并将错误代码1001返回到操作系统。

 

2.为什么a[5]=5[a]?

 

A[b]是指按C标准计算的*(a+b)。a是基址,b是从a开始的偏移量。a[b]是a+b地址中的值。因此,+5和5+a是相同的内存地址。它们的值*(a+5)和*(5+a)是相同的。所以a[5]=5[a]

 

关于C/C+指针的5个问题

 

3.我们能有多少水平的指针?

 

人类所能承受的,任何C/C+编译器都绝对支持以上。

 

4.指向指针数组/数组的指针消歧

 

下列声明之间有什么区别:

int* arr1[8];int (*arr2)[8];int *(arr3[8]);
   

根据C优先级表,数组[],函数RETURE()比指针*具有更高的优先级。

 

关于int*第1条[8]

arr 1首先是一个数组,不管元素是什么类型。在应用指针*之后,我们知道arr 1是一个int指针数组。

 

关于int(*第2条)[8]

根据括号重写规则,在这种情况下,指针*比数组[]具有更高的优先级。那么arr 2首先是一个指针,不管它指向什么。在应用数组[]之后,我们知道arr 2是一个指向int数组的指针。

 

关于int*(第3[8]条)

在这种情况下,括号不会更改任何默认优先级,因此它与int*arr 1[8]相同。

 

关于C/C+指针的5个问题

 

5.指针有什么意义?

 

(1)voidfoo(int*Const PTR);


(2)voidfoo(int*PTR);

 

对于foo的调用方,PTR的值在(1)和(2)中都被复制到foo中。

 

(1)和(2)只对foo的实现者,而不是foo的客户端起作用。

 

在(2)中,实现者可能会意外地更改PTR的值,这可能会引入bug。

 

(1)就像实现者在编写foo正文之前对编译器说:“嘿,我不想对PTR进行估值,如果它以某种模糊的方式更改,那么编译失败,让我来检查一下。”

 

如果你想让别人读你的代码,请把代码放进去。<pre><code>和</code></pre>标签。例如: 

 

<pre><code> 
String foo = "bar";
</code></pre>

 

约翰·赖斯

“仅仅因为代码编译并不意味着它是有效的。有很多代码会编译,但会产生未定义的行为-从代码中调用main是标准明确不允许的。


仅仅因为IT与GCC一起编译并在您测试IT的每台机器上运行,就不能使其正确!

 

关于C/C+指针的5个问题

 

*·苏莱曼

请把整个代码粘贴到这里,我不明白你的想法

 

罗布·德斯博伊斯

>为什么这段代码是无效的答案?GCC编写得很好,完成了任务。你还期望什么?


仅仅因为代码编译并不意味着它是有效的。有大量的代码可以编译,但是会产生未定义的行为-在代码中调用main是标准明确不允许的。


答案是无效的C+,因为它直接调用main,而且它依赖于j值为1,这是不能保证的。换句话说,在不同的场景中,这段代码可以:完美地工作;计数从10到1000;计数从1001到1000…。漫长的道路;无限循环(由于调用main);呼叫终止();在火球中爆炸并导致计算机崩溃。

 

好的,最后一个不太可能但重点是没有指定行为,因此代码可能不可靠且不可移植。>您是对的‘voidmain(Int)’无效,是‘intmain(Int)’是。它实现是否按照C标准5.1.2.2.1定义;C+标准3.6.1.您提到的两个必须在除了编译器想要支持的任何内容之外。

你也是对的,我一定漏掉了那句话。

 

关于C/C+指针的5个问题

 

>知道[我们可以拥有多少级别的指针]除了编译器/工具编写器之外,没有任何帮助。也许不是,但这是问题的答案。你的答案是准确的,但不准确。如果我是在问这个问题,那么我希望得到的答案是确切的数字。当然,如果有的话,C+开发人员会发现这是一个实际的限制,但这并不能阻止它成为这个问题的准确答案。

 

迈克尔

不使用循环从1计数到1000
 

正确答案:
返回(1+1000)*1000/2;(没有循环,没有递归,没有棘手和不可读的代码,只是我们在小学到的规则)

 

罗布·德斯博伊斯

哇,在什么世界里“不使用循环从1数到1000”是C+指针的首要问题?这根本不是关于指针的问题。正如您所说,实现它的方法是递归,它也与指针无关。问题和指针之间的唯一联系是一个诡异的、人为的、无效的答案。


“根据C语言”声明某事是真实的,然后假设它对C+有效是一项冒险的事情:它可能是真的,也可能不是真的,因为C+不是C+的超集。

 

关于C/C+指针的5个问题


C.您关于C中为真的断言是不正确的:一般来说,如果程序是在没有参数的情况下调用的,则(j=1)将是正确的,但是标准允许此参数为0。


main()函数的签名无效;唯一标准支持的签名是int(Void)和int(int,char*[])。
然而,最重要的是:标准要求‘函数main不能在程序中使用’,这使得递归调用它的行为不明确。

 

为了补充您对问题3的回答:[C+11]标准将指针、数组和函数声明器修改类型的最小可接受的支持设置为256。

 

最后小编有彩蛋哦~

给大家准备了一份免费的C语言学习课程,赶紧来领取吧!

关于C/C+指针的5个问题