确定回文 - 运算符 * 是如何工作的?

发布于 2024-12-11 02:11:11 字数 1172 浏览 0 评论 0原文

该程序应该接受一个三位数并将其更改为回文数。 123 将变为 321

逻辑正确,程序编译正确。 :) 然而,这些逻辑并不容易实现。

我的教授用“堆栈图”解释了事情,我发现它们很有帮助。我根据另一个程序创建了这个程序,因为我注意到它与我制作的不同程序之间的相似之处,但是指向是如何工作的呢?

#include <stdio.h>

void reverse_number(int in_val, int *out_val) {
    int ones, tens, hundreds;

    ones = in_val % 10;
    tens = (in_val % 100 - ones) / 10;
    hundreds = (in_val - (ones + tens)) / 100;

    *out_val = (ones * 100) + (tens * 10) + hundreds;
}

int main() {
    int in_val;
    int out_val;

    printf("Give a three digit num to reverse: \n");
    scanf("%d", &in_val);

    reverse_number(in_val, &out_val);
    printf("New number is: %d \n", out_val);

    return 0;
}

另外,我现在开始了解如何基于带有这些指针的模板编写程序,并且我基本上了解参数内的星号意味着什么(声明为指针变量)。

例如,我知道 m = &q; 为变量 m 提供了另一个变量 q 的地址,并且我知道 m = *g; 意味着地址 g 处的值将进入 m 但我真的不熟悉它们在函数上下文中如何工作和一个主文件。

如果有人能够阐明它(在这个程序中)如何工作的基本逻辑,那就太棒了。作为一名数学专业的学生,​​我可以理解数学和其他东西的运算,但指针并没有让我感到困惑,但在我看来,有一些方法可以做到这一点,而无需处理变量的地址等。

This program is supposed to take in a three digit number and change it into its palindrome. 123 would become 321.

The logic is correct, and the program compiles correctly. :) However, the logic of these does not come easily.

My prof explains things with "stack diagrams" and I find them to be helpful. I created this program based off another program because I noticed the similarities between this and a different program I made, but how does the pointing work?

#include <stdio.h>

void reverse_number(int in_val, int *out_val) {
    int ones, tens, hundreds;

    ones = in_val % 10;
    tens = (in_val % 100 - ones) / 10;
    hundreds = (in_val - (ones + tens)) / 100;

    *out_val = (ones * 100) + (tens * 10) + hundreds;
}

int main() {
    int in_val;
    int out_val;

    printf("Give a three digit num to reverse: \n");
    scanf("%d", &in_val);

    reverse_number(in_val, &out_val);
    printf("New number is: %d \n", out_val);

    return 0;
}

Also, I am now beginning to understand how to write programs based on a kind of template with these pointers, and I understand very basically what the star inside a parameter means (declared as a pointer variable).

For example, I know that m = &q; gives variable m the address of another variable q and I know that m = *g; would mean that the value at the address g would go into m but I am really unfamiliar with how these work in the context of a function and a main file.

If someone could lay out the fundamental logic of how it would work (in this program) that would be awesome. As a math major, I can understand the operations of the math and stuff but the pointers have me not confused but it just seems to me that there are ways to do it without needing to deal with the address of a variable, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风吹过旳痕迹 2024-12-18 02:11:11

当我运行它时,它会编译,甚至可以工作。请参阅: http://ideone.com/RHWwI

所以这一定是你编译它的方式。你的编译器错误是什么?

When I run it, it compiles, and even works. See: http://ideone.com/RHWwI

So it must be how you're compiling it. What is your compiler error?

濫情▎り 2024-12-18 02:11:11

好吧,既然您完全理解了 &* 运算符,那么剩下的就非常非常简单了。

假设您有:

int q;
int *m;
m = &q;

那么如果您说:

int *m2;
m2 = m;

m2 将包含与 m 相同的值,即,它将具有 q 的地址。因此,*m*m2 将为您提供相同的值(即 q 的值)(您做 明白 *& 的逆运算符吗?所以 *(&q) = q& (*m) = m(在后一种情况下, m 需要是 * 的指针才适用。))

那么,这如何与函数一起使用?简单的!当您将参数传递给函数时,您是按值传递它们。当你传递指针时,你实际上是在传递值,即变量的指针。

因此,让我们详细检查您的函数调用:

reverse_number(in_orig, &out_orig);

我将 main 中的 in_valout_val 重命名为 in_origout_orig因此它不会与 reverse_number 的内容混合。

现在,&out_origout_orig 的地址。当作为参数传递时,它会被复制到 reverse_numberout_val 参数中。这与写作完全一样:

int *out_val = &out_orig;

现在,如果您的 main 中有上述行,您只需编写 *out_val = Something; ,它就会改变 out_orig< /代码>,对吧?好吧,既然您在 out_val 中有 out_orig 的地址,那么谁在乎 *out_val 是否在 main 中设置> 或reverse_number

所以你看到了吗?当你有一个指针时,你可以复制它,无论是将它复制到另一个变量还是将它作为函数的参数传递(这基本上是同一件事),你仍然可以访问它指向的同一个变量。毕竟,所有副本都具有相同的值:out_orig 的地址。现在,如果您想在函数或 main 中访问它,这并不重要。

编辑:指针定义中的*

*也可以用来定义指针,这与之前的用法无关* 作为获取地址值的运算符。

这只是定义,所以你必须学习它:

如果你有一个 type 类型的值(例如 int),那么该变量的地址(使用 >operator &) 的类型为 type *(在此示例中为 int *)。由于指针采用该地址,因此指针的类型为type *

相反,如果指针的类型为 type *(例如 int *),则获取指针指向的值(使用 operator *) 的类型为 type(在此示例中为 int)。

总而言之,您可以这样说:

operator &, adds one * to the type of the variable
operator *, removes one * from the type of the expression

让我们看一些示例:

int x;
x has type int
&x has type int *

float *y;
y has type float *
&y has type float **
*y has type float

struct Data ***d;
d has type struct Data ***
&d has type struct Data ****
*d has type struct Data **
*(*d) has type struct Data *
*(*(*d)) has type struct Data

如果您注意到的话,我说过 &变量的类型添加了一个 * ,但*表达式的类型中删除一个*。这是为什么?因为 & 给出了变量的地址。当然,因为没有其他东西有地址。例如,a+b(可能)在内存中没有任何地址,即使有,它也只是暂时的且无用的。

然而,operator * 适用于地址。无论您如何计算地址,operator * 都会对其进行处理。示例:

*(0x12345678) -> Note that even if the compiler let's you do this,
                 your program will most likely crash

*d -> like we saw before

*(d+4) -> This is the same as writing d[4]
          And now you know why arrays and pointers are treated as one

如果是动态二维数组:

*(*(d+4)+6) -> This is the same as writing d[4][6]

Well, since you understood & and * operators perfectly, the rest is very very simple.

Let's say you have:

int q;
int *m;
m = &q;

Then if you say:

int *m2;
m2 = m;

m2 will contain the same value as m, that is, it will have the address of q. Therefore, *m and *m2 will give you the same value (which is the value of q) (you do understand that * is the inverse operator of & right? So *(&q) = q and &(*m) = m (in the later case, m needs to be a pointer for * to be applicable.))

So, how does this work with functions? Simple! When you pass arguments to functions, you pass them by value. When you pass by pointer, you are actually passing by value, the pointer of the variable.

So let's examine your function call in detail:

reverse_number(in_orig, &out_orig);

I renamed your in_val and out_val in the main to in_orig and out_orig so it won't get mixed with those of reverse_number.

Now, &out_orig is the address of out_orig. When passed as arguments, this gets copied into out_val argument of reverse_number. This is exactly like writing:

int *out_val = &out_orig;

Now, if you had the above line in your main, you could just write *out_val = something; and it would change out_orig, right? Well, since you have the address of out_orig in out_val, then who cares if *out_val is being set in main or reverse_number?

So you see? When you have a pointer, you can just copy it around, whether by copying it to another variable or passing it as argument of a function (which is basically the same thing), you can still access the same variable it is pointing to. After all, all the copies have the same value: address of out_orig. Now if you want to access it in a function or in main, it doesn't really matter.

Edit: * in pointer definition

* can be used to define a pointer too and this has nothing to do with the previous usage of * as an operator that gets the value of an address.

This is just definition, so you have to learn it:

If you have a value of type type (for example int), then the address of that variable (using operator &) has type type * (in this example int *). Since a pointer takes that address, the type of the pointer is type *.

On the contrary, if a pointer has type type * (for example int *), then getting the value where the pointer points to (using operator *) has type type (in this example int).

In summary, you can say something like this:

operator &, adds one * to the type of the variable
operator *, removes one * from the type of the expression

So let's see some examples:

int x;
x has type int
&x has type int *

float *y;
y has type float *
&y has type float **
*y has type float

struct Data ***d;
d has type struct Data ***
&d has type struct Data ****
*d has type struct Data **
*(*d) has type struct Data *
*(*(*d)) has type struct Data

If you noticed, I said that & adds one * to the type of variable, but * removes one * from the type of expression. Why is that? Because & gives the address of a variable. Of course, because nothing else has an address. For example a+b (possibly) doesn't have any address in the memory, and if it does, it's just temporary and useless.

operator * however, works on addresses. No matter how you compute the address, operator * works on it. Examples:

*(0x12345678) -> Note that even if the compiler let's you do this,
                 your program will most likely crash

*d -> like we saw before

*(d+4) -> This is the same as writing d[4]
          And now you know why arrays and pointers are treated as one

In case of a dynamic 2d array:

*(*(d+4)+6) -> This is the same as writing d[4][6]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文