指针和赋值,它如何与不同类型一起使用?
我正在通过了解一点Python来“自学”“学习C”。 我已经阅读了几个教程,但我无法理解指针和赋值是如何工作的。 我知道如果你取消引用指针,你可以直接给它一个值,如:
int *anint = 42;
但是具体引用已经创建的变量的内存位置呢? 具体来说,我尝试过:
char *pointer_to_strlit; char *strlit = "some stuff"; pointer_to_strlit = &strlit;
为什么在执行此操作后,以下内容会导致段错误:
printf("I print strlit: %s\nI print it again by pointing to it: %s\nI print where the pointer is pointing: %p\n", strlit, *pointer_to_strlit, pointer_to_strlit);
C中的类型似乎很难说明它们将如何表现以及如何使用指针来引用特定类型。 是否有明确的指南专门概述了指向每种不同数据类型的语法( char
, *char
, *char[]
, int
, struct
, void
, null
,functions等)? 即使是一个有助于我理解规则集的步骤列表也会很有用。
在那里挂! 更多练习后,指针会有意义。 但如有疑问,请尝试推断每个价值的含义。 使用笔和纸来尝试在内存中绘制每个字节确实有帮助。
char *pointer_to_strlit;
– 在这里你声明一个指向角色的指针。 您可能已经知道,C中的字符串由指向该字符串的第一个字符的指针表示。 该字符串应该以null结尾。 这意味着最终应该有一个ASCII 0
字符表示该字符串已结束。
char *strlit = "some stuff";
– 你的程序的内存将包含这个字符串的字符(准确地说是11个字符 – 你看到的文本是10个,空终止符是1个)。 在这里你声明另一个指针,这次指向该字符串中的第一个字符“s”。
pointer_to_strlit = &strlit;
– 这将pointer_to_strlit
的值设置为指针strlit
的地址 。 这可能不是你想要的。
如果事情变得混乱,请尝试将每个指针视为一个普通的旧数字 – 这实际上是一个指针,一个代表内存中地址的巨大数字。 让我们再看一遍:
char *pointer_to_strlit;
– 这里, pointer_to_strlit
的值是未定义的,因为你还没有设置它。
char *strlit = "some stuff";
– 假设第一个“s”的地址是1234500
。 strlit
的值将是该数字1234500
。
pointer_to_strlit = &strlit;
– 但是strlit
本身的地址是strlit
? 这是其他一些价值,比方说1234600
。 pointer_to_strlit
的值现在为1234600
。
现在尝试将pointer_to_strlit
打印为%s
,程序将崩溃 – 地址1234600
不是字符串的第一个字符,而是另一个数字 – 巨大数字的字节之一,指针。 代码将尝试遍历它认为是字符串以查找空终止符,最终在到达不可访问的内存时崩溃。
int *anint = 42;
42是整数文字,并且anint
应该保持指向整数的地址而不是整数本身。
char *pointer_to_strlit; char *strlit = "some stuff"; // Should be const char *strlit = "some stuff"; pointer_to_strlit = &strlit; // Wrong
&strlit
给出指针的地址(即char **),而pointer_to_strlit
的类型为char *。 所以,它应该是
pointer_to_strlit = strlit;
字符串文字位于只读位置。 打开警告,编译器应该给你一些体面的消息。
int *anint = 42;
此声明不正确。 anint
是指向int的指针,但是您已将其初始化为int。
char *pointer_to_strlit; char *strlit = "some stuff";
这些声明没问题。 "some stuff"
是一个字符串文字,在C中是一个char *
,因此可以用它来初始化strlit
。
pointer_to_strlit = &strlit;
这是不正确的。 &strlit
是一个char**
,因为它是char*
的地址。
printf( "I print strlit: %s\n" "I print it again by pointing to it: %s\n" "I print where the pointer is pointing: %p\n", strlit, *pointer_to_strlit, pointer_to_strlit );
在这里你使用strlit
作为%s
,这很好。 然后你使用*pointer_to_strlit
作为%s
,这是坏的: %s
期望一个指向以null结尾的字符串的指针,你给它一个char
,所以它是segfaults。