Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C while()循环继续意外迭代_C_Pointers_While Loop - Fatal编程技术网

C while()循环继续意外迭代

C while()循环继续意外迭代,c,pointers,while-loop,C,Pointers,While Loop,1) 为什么我总是得到像“我得到了c”这样的答案 2) 不管我执行这个程序多少次,为什么我得到了%c作为c 3) 用任意字符替换c字符,不管我们为什么得到这样一个字符,我们在if条件下放了什么 program int main() { int a=0xabcd; char *p=&a; while(p) { if(*p=='c') { printf("i got %c\n",*p);

1) 为什么我总是得到像“我得到了c”这样的答案 2) 不管我执行这个程序多少次,为什么我得到了%c作为c
3) 用任意字符替换c字符,不管我们为什么得到这样一个字符,我们在if条件下放了什么

program
int main()
{
    int a=0xabcd;
    char *p=&a;
    while(p)
    {
        if(*p=='c')
        {
            printf("i got %c\n",*p);
            return; 
        }
        p++;
    }

}
4) 有人能解释一下原因吗?

  • 32位机器上的int a=0xabcd将为您提供
    0x0000abcd
    。如果您尝试以字符形式读取此整数的内容,您将获得0x00或0xcd,具体取决于endianess。两者都不是可打印的ASCII字符。这没有任何意义

  • while(p)
    表示“whilep指向的地址不是零”。这没有任何意义。因此,您将继续循环并读取分配整数之外的随机内存单元。任何事情都有可能发生。如果幸运的话,程序将崩溃

总而言之,您似乎不太清楚自己在做什么…

1)您得到了
我得到了c
,因为您的程序有一个指针
p
,它按顺序指向0xabcd的每个字节甚至更远!在某一点上,指针将指向字节0x63,即“c”。由于这是
if
条件,print语句将打印p所指的字符,您将看到消息
i got c

2) 由于if条件,仅当p所指的字节为0x63时才执行print语句,因此为“c”。这就是为什么你总是看到相同的信息。但是请注意,只有当内存中某处有一个值为0x63的字节时,它才起作用

3) 您可以这样写以显示其他字符

if(*p=='z') or if(*p=='t') or .... 

4) 参见以上答案。

除了伦丁先生的漂亮答案之外,为了澄清印刷品的逻辑

1) 为什么我总是得到像“我得了c”这样的答案

因为,您编写了这样做的代码。为了避免编程错误,如果检查逻辑,则编写代码,以便只有当
*p
的值等于
c
时才会执行
printf()
。因此,难怪
printf()
(如果遇到)会一直打印

if((*p=='z') || (*p=='t') || ....) 
其次,

2) 不管我执行这个程序多少次,为什么我得到%c作为c

对。原因同上

3) 用任意字符替换c字符,不管我们为什么得到这样一个字符,我们在if条件下放了什么


只有当满足
条件时,才会执行
printf()
。因此,无论在
if
条件中使用什么字符,
printf()
将只打印该字符。

您似乎不知道自己在做什么

最接近的工作示例如下所示:

i got c
#包括
int main()
{
int a[2]={0x0a0b0c0d,0};
char*p=(char*)a;
而(*p)
{
如果(*p==0x0c)
{
printf(“我得到了c\n”);
返回0;
}
p++;
}
}
或者另一个更好的解决方案:

#include <stdio.h>

int main()
{
    int a[2] = {0x0a0b0c0d, 0};
    char *p = (char *) a;

    while (*p)
    {
        if (*p == 0x0c)
        {
            printf("i got c\n");
            return 0; 
        }
        p++;
    }

}
#包括
int main()
{
int a=0x0a0b0c0d;
对于(int i=0;i
而(p)
看起来很奇怪。@SouravGhosh:。。。因为指针运算超出了数组的边界。在找到要查找的字符或程序崩溃之前,程序不会停止扫描内存。所以我不确定你希望程序做什么,崩溃?
char*p=&a格式不正确,因此整个程序的行为未定义。你的意思可能是
char*p=(char*)&a。如果您的编译器没有报告此情况,则使用编译器开关激活其一致性模式。OP的
while(p)
可能应该是
while(*p)
@HolyBlackCat,这到底有什么意义?如果
char a=“abcd”
char*p=a。我认为程序在找到二进制“c”之前崩溃和烧坏的可能性要大得多。但是OP可能是DOS程序员之一……这取决于操作系统。不管是否有这样的字节,循环都会导致UB,因此编译器可以做任何事情。它可以优化代码以删除循环并输出字符串,而不必读取任何内存。@Matt McNabb这会令人惊讶。这是一些讨论。除了这是一个事实,它的UB无论如何读取超出分配的内存;编译器可以假定不存在没有输出的无限循环。由于该循环只有一个出口点,因此必须达到该出口点。(
while(p)
可以推断,除非UB发生过,否则永远不会是假的)为什么要重复已经给出两次的解释?实际上,程序在崩溃之前是否会打印“i Get c”是一个小小的奇迹。哦,通过调用未定义的行为,奇妙的事情成为可能@哇!!对不起,这就是投否决票的原因吗?顺便说一句,谢谢你花时间发表评论。:-)@这似乎不是完全相同的解释。对同一主题的不同观点是有用的,因为你永远不知道用哪种方式来解释某个人会觉得有帮助,适合他们的知识、语言、推理方式,等等。你怎么知道这是他想要做的?@chmike我无法想象OP的程序还能做什么。我无法想象OP可能会做什么。@HolyBlackCat
char*a=“abcd”;char*p=a;而(*p){if(*p=='c')…
#include <stdio.h>

int main()
{
    int a = 0x0a0b0c0d;

    for (int i = 0; i < sizeof (int); i++)
    {
        if(((char *) &a)[i] == 0x0c)
        {
            printf("i got c\n");
            return 0; 
        }
    }

}