[英]C Programming Simple Pointers
我是学习指针的初学者。 这是我的代码。 (注意:我仍然试图绕过指针,所以我的代码不干净。)
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]){
int a = 1;
char b = 's';
double c = 3.14;
int *ptra;
int *ptrb;
int *ptrc;
ptra = &a;
ptrb = &b;
ptrc = &c;
printf("I initialised int as %d and char as %c and double as %.2f\n", a, b, c);
printf("The address of A is %p and the contents of A is %d\n", ptra, *ptra);
printf("The address of B is %p and the contents of B is %c\n", ptrb, *ptrb);
printf("The address of C is %p and the contents of C is %.2f\n", ptrc, *ptrc);
我期待以下输出:
I initialised int as 1 and char as s and double as 3.14
The address of A is 0xbf933094 and the contents of A is 1
The address of B is 0xbf933093 and the contents of B is s
The address of C is 0xbf933098 and the contents of C is 3.14
但相反,我得到了这个:
I initialised int as 1 and char as s and double as 3.14
The address of A is 0xbf933094 and the contents of A is 1
The address of B is 0xbf933093 and the contents of B is s
The address of C is 0xbf933098 and the contents of C is 427698.00000
在打印C的内容时,有人可以为我获得的大量数据提供帮助吗? 为什么我得不到3.14? (这个数字实际上比这长,但它不适合这个文本框。:-))
您将ptra
, ptrb
和ptrc
声明为指向int
的指针。 但是指针的类型是基于它所指向的,所以它应该是:
int *ptra;
char *ptrb;
double *ptrc;
在您的特定情况下,您的程序正在尝试通过int
指针解释double
值。 由于这些数据类型的大小在您的机器上有所不同,因此双倍的某些位被丢弃,您最终得到了您所看到的奇怪数字。
这可能并不总是以相同的方式发生 - 通过错误类型的指针访问某些内容的结果不是由C语言定义的,但它仍然可以编译。 C程序员将此称为未定义的行为 (如果你想学习C,你应该真正接受这个术语!)。
还有一个事实是,当你调用printf
,你需要从格式字符串中为它提供所需类型的变量。 因此,如果你给它一个格式字符串,其中第一个占位符是%.f
,你必须给它一个双重的第一个参数。 如果不这样做, printf
也会表现出未定义的行为并且可以做任何事情(未定义的行为可能是奇怪的输出,崩溃,或者只是输出你期望的数字......直到最糟糕的时刻)。
你的指针都是int
类型。 这是不正确的。 替换那些
int *ptra;
char *ptrb;
double *ptrc;
因为你的指针都是int*
。 如果你想要它取消引用一个double
,你需要它是double*
。 您的编译器应该警告您不兼容的指针赋值。
您应该使用相应的类型声明指针。
int *ptra;
char *ptrb;
double *ptrc;
您需要更改指针类型以匹配您的数据类型,以便相应地设置大小。
char *ptrb;
double *ptrc;
如果我只能说一下关于打字指针的话。
带有类型的指针(与void*
指针相对)知道要在内存中前进多少字节。 例如,在32位系统上,当遍历包含整数值的数组时,整数指针通常会在内存中前进4个字节。
char指针(由C标准保证始终为1字节)自然会一次前进1个字节。
让我用一个小代码片段来说明这一点:
#include <stdio.h>
int main()
{
char array [] = "This is a char array.";
int* int_ptr;
char* char_ptr;
char_ptr = array; /* This is okay, we have a char array and we assign its address to a char pointer */
int_ptr = array; /* It will complain but let's go along with it */
printf("%p, %p, %p\n", array, char_ptr, int_ptr); /* They should all point to the same address in memory */
printf("%p\n", ++char_ptr); /* it will have advanced by one byte */
printf("%p\n", ++int_ptr); /* it will have advance by four bytes */
return 0;
}
我的机器上有以下输出:
$ ./a.out
0xbf8b85d2, 0xbf8b85d2, 0xbf8b85d2
0xbf8b85d3
0xbf8b85d6
正如你所看到的,他们确实已经按照我们的预测进步。 很明显,当我们开始取消引用我们的指针并且它们与底层类型不匹配时,这会导致各种各样的问题。
关于void*
指针, 对它们的算术是非法的 。
这里指针ptrc是指可变数据的地址,其数据类型是整数,但是你将它用于double。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.