繁体   English   中英

C编程简单指针

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

您将ptraptrbptrc声明为指向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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM