2

我是学习指针的初学者。这是我的代码。(注意:我仍在努力解决指针问题,所以我的代码不会很干净。)

#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?(这个数字实际上比那个长,但它不适合这个文本框。:-))

4

7 回答 7

5

您正在声明ptra,ptrbptrc作为指向ints 的指针。但是指针的类型是基于它所指向的,所以它真的应该是:

int    *ptra;
char   *ptrb;
double *ptrc;

在您的特定情况下,您的程序正试图double通过int指针解释一个值。由于这些数据类型的大小在您的机器上有所不同,因此 double 的某些位会被丢弃,您最终会看到您看到的奇怪数字。

这可能并不总是以同样的方式发生——通过错误类型的指针访问某些东西的结果不是由 C 语言定义的,但它仍然可以编译。C 程序员将此称为未定义行为(如果您想学习 C,您应该真正接受这个短语!)。

还有一个事实是,当您调用 时printf,您需要为其提供格式字符串所期望的类型的变量。因此,如果你给它一个格式字符串,其中第一个占位符%.f,你必须给它一个双精度参数。如果你不这样做,printf也会表现出未定义的行为并且可以做任何事情(未定义的行为可能是奇怪的输出,崩溃,或者只是把你期望的数字......直到最糟糕的时刻)。

于 2013-06-24T02:11:10.903 回答
2

您的指针都是 type int。这是不正确的。替换那些

int *ptra;
char *ptrb;
double *ptrc;
于 2013-06-24T02:10:57.670 回答
2

因为你的指针都是int*. 如果你想让它取消引用 a double,你需要它是double*。您的编译器应该警告您不兼容的指针分配。

于 2013-06-24T02:11:41.723 回答
1

您应该使用相应的类型声明指针。

int *ptra;
char *ptrb;
double *ptrc;
于 2013-06-24T02:12:32.420 回答
1

您需要更改指针类型以匹配您的数据类型,以便相应地设置大小。

char *ptrb;
double *ptrc;
于 2013-06-24T02:14:23.043 回答
0

这里的指针 ptrc 指的是数据类型为整数的变量的地址,但您将它用于双精度。

于 2013-06-24T06:53:07.787 回答
0

如果我能说几句关于类型化的指针的话。

具有类型的指针(与void*指针相反)知道要在内存中推进多少字节。例如,在 32 位系统上,整数指针在遍历包含整数值的数组时通常会在内存中提前四个字节。

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*指针,对它们的算术是非法的

于 2013-06-24T03:07:40.473 回答