char和int的指针

时间:2013-06-06 18:28:16

标签: c pointers char int

嗨,我有一个简单的问题

char *a="abc";
printf("%s\n",a);

int *b;
b=1;
printf("%d\n",b);

为什么第一个有效但第二个有效? 我认为第一个应该是

char *a="abc";
printf("%s\n",*a);

我认为存储“abc”的地址。那么为什么我在打印时会显示abc?我想我应该打印* a来获得它的价值。

由于

2 个答案:

答案 0 :(得分:3)

  

为什么第一个有效但第二个无效?

因为在第一个中,你不是要求它打印一个字符,你要求它以字符串形式打印一个以空字符结尾的字符数组。

这里的混乱是你将字符串视为“本机类型”,与整数和字符的方式相同。 C不起作用;字符串只是指向以空字节结尾的一堆字符的指针。

如果您真的想将字符串视为本机类型(请记住它们确实不是),请以这种方式考虑它:字符串的类型是char *,而不是{{1} }。因此,char有效,因为您传递printf("%s\n", a);以匹配指示char *的格式说明符。要获得与第二个示例相同的问题,您需要将指针传递给字符串 - 即char *

或者,相当于char **不是%d,而是%s,它会打印一个字符。要使用它,你必须传递一个字符。 %c会遇到与printf("%c\n", a)相同的问题。


来自你的评论:

  

我认为存储“abc”的地址。那么为什么我在打印时会显示abc?我想我应该打印* a来获得它的价值。

这是对作为原生对象的字符串的松散思考。

当你这样写:

printf("%d\n", b)

编译器会存储一个包含四个字符的数组 - char *a = "abc"; 'a''b''c' - 某处和'\0'点在第一个,a。只要你记得a实际上是一个由四个独立字符组成的数组,将"abc"视为指向该事物的指针是有意义的(至少如果你理解了数组和指针算法是如何工作的话) C)。但如果您忘记了这一点,如果您认为a指向的是包含单个对象a的单个地址,则会让您感到困惑。


GNU printf man page引用(因为C标准不可链接):

  

d,我

     

int参数转换为带符号的十进制表示法......

     

C

     

...将int参数转换为unsigned char,并生成结果字符......

     

取值

     

... const char *参数应该是指向字符类型数组(指向字符串的指针)的指针。数组中的字符被写入(但不包括)终止空字节('\ 0')...


最后一件事:

如果没有“字符串”这样的值,您可能想知道"abc"printf("%s", a)或任何其他函数如何打印或搜索字符串。

他们正在使用一种约定:他们使用指向字符的指针,并从那里打印或搜索每个字符直到第一个空值。例如,您可以编写strchr(a, 'b')函数,如下所示:

print_string

或者:

void print_string(char *string) {
    while (*string) {
        printf("%c", *string);
        ++string;
    }
}

无论哪种方式,您都假设void print_string(char *string) { for (int i=0; string[i]; ++i) { printf("%c", string[i]); } } 是指向字符数组开头的指针,而不是仅指向单个字符,并打印数组中的每个字符,直到您点击空字符。这是“空终止字符串”约定,它被整合到标准库中的char *printf等函数中。

答案 1 :(得分:1)

字符串在C语言中并不是真正的“一等公民”。实际上,它们只是作为以空字符结尾的字符数组实现的,并且引入了一些语法糖以使程序员的生活更轻松。这意味着当传递字符串时,你通常会通过char *变量来做 - 也就是指向以char为空的终止数组的指针。

这种做法也适用于调用printf%s格式与char *参数匹配以打印字符串 - 就像您所见。您可以使用*a,但是您希望将其与%c或整数格式匹配,以仅打印指向的单个字符。

出于几个原因,你的第二个例子是错误的。首先,如果没有C中的显式转换,则进行作业b = 1是不合法的 - 您需要b = (int *)1。其次,您正在尝试打印指针,但是您使用%d作为格式字符串。这也是错的 - 您应该使用%p,如下所示:printf("%p\n", (void *)b);

在第二个例子中你尝试的真实情况是:

int b = 1;
int *p = &b;
printf("%d\n", *p);

即,创建一个指向整数的指针,然后取消引用它并将其打印出来。

编辑说明:你应该得到一本好的初学C书(在这里搜索,我相信你会找到建议)并通过它来完成。