简体   繁体   English

C:指针混淆

[英]C: Pointer confusion

I understand this is part of the basic stuff, but i am stuck:-( Can someone please help me?我知道这是基本内容的一部分,但我被卡住了:-(有人可以帮我吗?

Program 1:方案一:

#include <stdio.h>
#include <stdlib.h> 

int main()
{
 int a=1,b=2,c;
 c=(a+b)++;
}

Why is the output an error?为什么 output 出现错误? lvalue required?需要左值吗?

Program 2:方案二:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
 char *p1="name";
 char *p2;

 p2=(char*)malloc(20);
 memset(p2,0,20);

 while(*p2++=*p1++);
 printf("%s\n",p2);

}

Why is the output, an empty string?为什么 output 是空字符串? And if i reverse the order of increment, that is: while(++*p2=++*p1);如果我颠倒递增的顺序,即: while(++*p2=++*p1); , why the lvalue error comes? ,为什么会出现左值错误?

For the first question, (a+b)++ means "increment the value of a+b by 1".对于第一个问题, (a+b)++表示“将a+b的值增加 1”。

You cannot increment a+b , though, for it's not a variable.但是,您不能增加a+b ,因为它不是变量。 What would you expect to happen in the following code?您希望在以下代码中发生什么?

int a = 1, b = 2;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);
(a+b)++;
printf("a = %d, b = %d, a+b = %d\n", a, b, a+b);

Clearly the first printf should print显然第一个printf应该打印

a = 1, b = 2, a+b = 3 a = 1, b = 2, a+b = 3

But what about the second one?但是第二个呢?

a =?, b =?, a+b = 4 a =?, b =?, a+b = 4

It's not clear what a or b should be if we increment the sum.如果我们增加总和,不清楚 a 或 b 应该是什么。

As for the second question, remember that you're changing p2 when you copy over the data, so when you ask to print out what it's pointing at, it's pointing at the end of the string, not the beginning.至于第二个问题,请记住您在复制数据时正在更改p2 ,因此当您要求打印它所指向的内容时,它指向的是字符串的末尾,而不是开头。

An easier way to do the string copy would be to use strcpy , like so:进行字符串复制的一种更简单的方法是使用strcpy ,如下所示:

strcpy(p2, p1);

Note, this is only safe because you know that the size of the string in p1 isn't greater than the size of p2 .请注意,这只是安全的,因为您知道p1中字符串的大小不大于p2的大小。 If you're not sure about the size of the string (for instance, if you get the string from user input), you'll need to be careful, as is outlined on Wikipedia .如果您不确定字符串的大小(例如,如果您从用户输入中获取字符串),则需要小心,如 Wikipedia 中所述

As for why while(++*p2=++*p1);至于为什么while(++*p2=++*p1); doesn't work, while while(*p2++=*p1++);不起作用,而while(*p2++=*p1++); does:做:

Postfix- ++ has higher precedence than * . Postfix- ++的优先级高于* This means, *p2++ means *(p2++) .这意味着, *p2++表示*(p2++) So所以

*(p2++) = something;

is the same as是相同的

*p2 = something;
p2 += 1;

Meanwhile, ++*p2 means ++(*p2) , or "whatever p2 points to, incremented by one".同时, ++*p2表示++(*p2) ,或“无论p2指向什么,都加一”。

Again, you get the problem, if you say:同样,如果您说:

 int a = 5, *p2 = &a;
 ++*p2 = 10;
 printf("a = %d\n", a);

What would you expect this to print?你希望这会打印什么? If anything, it should print 9, because you're telling the compiler that *p2+1 = 10 .如果有的话,它应该打印 9,因为你告诉编译器*p2+1 = 10

You can't expect a C-compiler to solve that equation, however, so in order to keep the language simple and efficient, this sort of thing is forbidden.但是,您不能指望 C 编译器解决该等式,因此为了保持语言的简单和高效,这种事情是被禁止的。

c=(a+b)++;

a+b is not a lvalue - how would you want to assign something to the result of an addition (a rvalue) - and the ++/-- operators do assign the new value. a+b不是左值 - 你想如何为加法的结果(右值)分配一些东西 - 并且 ++/-- 运算符确实分配了新值。

while(*p2++=*p1++);

You p2 points at the \0 at the end of the string.您 p2 指向字符串末尾的\0 You need to store the original address p2 points to before your loop:您需要在循环之前存储 p2 指向的原始地址:

char *p3 = p2;
while(*p2++=*p1++)
    ;
printf("%s\n",p3);
c=(a+b)++;

The ++ operator doesn't work with temporary variables. ++运算符不适用于临时变量。 (a+b) forms a temporary. (a+b) forms 临时。

while(*p2++=*p1++);

You're incrementing p2 here.你在这里增加p2 After the loop, p2 no longer points to the beginning of the memory block returned by last malloc() call.循环之后, p2不再指向上次malloc()调用返回的 memory 块的开头。

If you look at the while loop:如果您查看 while 循环:

while(*p2++ = *p1++);而(*p2++ = *p1++);

remember that an expression is "True" in C if it is non-zero, and false if it is zero.请记住,如果表达式不为零,则 C 中的表达式为“真”,如果为零,则为假。 Even though the loop has no body, the flow of control is still:即使循环没有主体,控制流仍然是:

check condition -> execute statement in body --> check condition检查条件 -> 在正文中执行语句 -> 检查条件

and here, "check condition" means "evaluate the statement and see if it is non-zero".在这里,“检查条件”的意思是“评估语句并查看它是否非零”。

The while loop continues to operate until p1 points to zero, at which point control passes to printf. while 循环继续运行,直到 p1 指向零,此时控制传递给 printf。

eg例如

int main() 
{
    int array1[] = {2, 3, 1, 0, 3, 5};
    int array2[20];
    int * p2 = (int *)memset(array2, 0, 20*sizeof(int));
    int * p1 = array1;

    while(*p2++ = *p1++) {
        printf("In while: p1 is %d\n", *p1);
    }
    printf("Out of while: %d\n",*p2);
    return 0;

}

yields:产量:

In while: p1 is 3
In while: p1 is 1
In while: p1 is 0
Out of while: 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM