- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
考虑:
#include<stdlib.h>
#include<stdio.h>
struct node {
int val;
struct node *next;
};
typedef struct node item;
void main() {
item * curr, *head;
int i;
head = NULL;
for (i = 1; i <= 10; i++) {
curr = (item *)malloc(sizeof(item));
curr->val = i;
curr->next = head;
head = curr;
}
curr = head;
while (curr) {
printf("%d\n", curr->val);
printf("%d\n", *curr);
curr = curr->next;
}
getchar();
}
当我打印出来时,*curr
和 curr->val
是一样的。为什么?
我对 *curr
感到困惑。我认为 *curr
是 &curr
指向的值。 (我是 C 语言的新手。)
最佳答案
首先,作为初学者,您应该尝试编写不引发警告的正确代码,然后再尝试理解幕后发生的事情以及为什么一些不正确的表达式仍然给出正确的结果。
C 是一种非常宽松的语言,只要编译器可以翻译它读取的内容,它通常会假定程序员知道他为什么编写它。这就是这里发生的事情。
在 C 中,struct
的地址可以转换为其第一个元素的地址。所以 (void *) &curr
与 (void *) &(curr->val)
相同。在这里,我将所有内容都转换为 void *
以确保具有兼容的指针类型。
这意味着 *((int *) curr)
是一个完美定义的 C 表达式,它的值确实是 curr->val
。但它是正确的,因为我写了一个明确的指针转换。
您编写的有效只是偶然,因为 curr
是聚合类型;您将 int
和 item *
传递给 printf
并仅使用它的第一个值 - 这不再标准C 和我只能假设一个经典 实现来猜测。但只需将您的打印命令替换为:
printf("%d - %d\n", curr->val, 12);
printf("%d - %d\n", *curr, 15);
你应该在第二个 printf
中看到垃圾,因为使用 %d
你声明你传递了一个简单的 int
而实际上传递了一个聚合.同样,每个标准都没有明确规定,但常见的实现应该会给出这个结果。
TL;DR: 由于 *curr
不是 int
,printf("%d\n", *curr );
是未定义的行为。这意味着任何事情都有可能发生,即使是预期的结果,但同一编译器或另一个编译器的不同版本,甚至编译参数的更改都可能产生不同的结果,代码中的微小更改也可能会产生不同的结果。
并且 C 允许自动将指针转换为 void *
并且您永远不应该转换 malloc
的返回值,因为它可以隐藏错误。请写:
curr = malloc(sizeof(item));
它不再与 C++ 兼容,但它是正确的 C。
关于c - 为什么 *curr 和 curr->val 的值相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38090856/
我创建了一个基本的控制台应用程序来进行这样的测试。 short val = 32767; val++; Console.WriteLine(val);
考虑下面的代码,我试图理解三种不同的数据绑定(bind)方法之间的区别。由于我是 Angular4 的新手,我需要弄清楚何时使用什么。例如要分配 ngModel,请使用 [(ngModel)]。要分配
我看到很多人使用各种不同的方法来检查变量是否为空,似乎真的没有达成共识。我听说 if($foo) 与 if(!empty($foo)) 或 if($foo != "")。 这是真的吗? 我知道这是一个
此代码有效: let mut b: Vec = Vec::with_capacity(a.len()); for val in a.iter() { b.push(val); } 此代码不起作
这可能是 bike-shedding ,但也许我遗漏了一些有趣的东西...... 如果一个类初始化一个成员val至 std::numeric_limits::infinity()后来想检查 val 是
我不知道如何以可搜索的方式表达我的问题,所以如果已经得到解答,请原谅我。我对 SQL 命令还不够熟悉,甚至无法为我指明正确的方向。我有一个连接另外两个表的 sqlite 表。示例: ╔═════╦══
这个似乎依赖于 Java 和 Kotlin 之间的交互,首先是一个 Java 类: public class MyJavaClass { private Runnable q; pub
这个问题已经有答案了: What does &= mean? [closed] (5 个回答) 已关闭 5 年前。 基本上试图找到汉明字符串 https://en.wikipedia.org/wiki
我只是创建一个函数,该函数将 JSON.stringify 输入,同时也会检测数字输入上的 NaN,但不想使用 typeof 由于以下原因。输入可以是数字、 bool 值或字符串。仅此而已。 我已经遇
我正在努力构建允许我从起始值过渡到目标最终值的公式,同时使用 Sin 或 Cos 波在指定时间内衰减? 我正在尝试使用 CSS 和 jsfiddle 模仿我在下面的示例中看到的弹跳效果。我制作这个示例
这个问题已经有答案了: Why are we not allowed to have assignment statements in the file scope in C? (2 个回答) Why
我有这个代码 January February 我用它来尝试获取值: $month = $("#month option:selected").val(); 但它返回文本“Janu
在我的 Kotlin 项目中,我想在编译时声明常量: 所以我用这个: @RunWith(AndroidJUnit4::class) class TradersActivityTest { pr
我是 Java 新手,我知道这是一个愚蠢的问题,但我无法理解 Java 初始化变量的方式。我尝试做一些测试,但我不知道这是如何工作的。 当我学习C或Java编程时,定义新变量的语法是这样的: type
我正在尝试在 kotlin 中编写一个函数,但我无法将值重新分配给函数参数,它说 val cannot be reassigned 。 class WebView{ var homepage
我将查询字符串传递到我的 Windows Phone 应用程序中的页面:page.xaml?key=val&key2=val . 我收到的是 NavigationContext.QueryString
我正在阅读 https://github.com/antirez/redis 中的 Redis 源代码. 我在src/ziplist.c中看到了这样的宏 #define INT24_MAX 0x7ff
我想知道下面两种情况有什么区别,推荐使用哪种? $val = 0; if (!$val) { //True } if (empty($val) { //It's also True } 最佳答
我理解在 Kotlin 中 const val 用于声明常量,而 val 用于只读属性。但是,我想知道在以下情况下,哪个更适合使用。 假设我有一个 fragment 需要一个用于 saveInstan
LinkedIn 问题 const val 可以做什么 @JvmField val 不能做什么? 关于 Val 和 const 之间的区别,有多种答案。canst Val 和 @JvmField Va
我是一名优秀的程序员,十分优秀!