字符指针和printf函数 [英] Char pointers and the printf function

查看:255
本文介绍了字符指针和printf函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习指针,并且编写了以下代码来打印指针的值:

I was trying to learn pointers and I wrote the following code to print the value of the pointer:

#include <stdio.h>

    int main(void) {
        char *p = "abc";
        printf("%c",*p);
        return 0;
    }

输出为:

a

但是,如果我将上面的代码更改为:

however, if I change the above code to:

#include <stdio.h>

int main(void) {
    char *p = "abc";
    printf(p);
    return 0;
}

我得到输出:

abc

abc

我不明白以下两件事:

  1. 为什么在第二种情况下printf不需要格式说明符? printf(pointer_name)是否足以打印指针的值?

  1. why did printf not require a format specifier in the second case? Is printf(pointer_name) enough to print the value of the pointer?

(很少),* p指向包含abc的连续内存块.我希望两个输出都相同,即

as per my understanding (which is very little), *p points to a contiguous block of memory that contains abc. I expected both outputs to be the same, i.e.

abc

abc

由于打印方式不同,输出是否不同?

are the different outputs because of the different ways of printing?

编辑1

此外,以下代码会产生运行时错误.为什么这样?

Additionally, the following code produces a runtime error. Why so?

 #include <stdio.h>

    int main(void) {
        char *p = "abc";
        printf(*p);
        return 0;
    }

推荐答案

第一个问题是

For your first question, the printf function (and family) takes a string as first argument (i.e. a const char *). That string could contain format codes that the printf function will replace with the corresponding argument. The rest of the text is printed as-is, verbatim. And that's what is happening when you pass p as the first argument.

请注意,强烈建议不要以这种方式使用printf,尤其是如果字符串包含用户输入的内容时.如果用户在字符串中添加了格式代码,而您没有提供正确的参数,那么您将具有未定义的行为.甚至可能导致安全漏洞.

Do note that using printf this way is highly unrecommended, especially if the string is contains input from a user. If the user adds formatting codes in the string, and you don't provide the correct arguments then you will have undefined behavior. It could even lead to security holes.

对于第二个问题,变量p指向一些内存.表达式*p取消引用指针以给您一个字符,即p实际指向的字符,即p[0].

For your second question, the variable p points to some memory. The expression *p dereferences the pointer to give you a single character, namely the one that p is actually pointing to, which is p[0].

这样想p:


+---+      +-----+-----+-----+------+
| p | ---> | 'a' | 'b' | 'c' | '\0' |
+---+      +-----+-----+-----+------+

变量p并不真正指向字符串",它仅指向内存中的某个单一位置,即字符串"abc"中的第一个字符.使用p的功能会将内存视为字符序列.

The variable p doesn't really point to a "string", it only points to some single location in memory, namely the first character in the string "abc". It's the functions using p that treat that memory as a sequence of characters.

此外,常量字符串文字实际上存储为字符串中字符数的(只读)数组,再加上一个用于字符串终止符的数组.

Furthermore, constant string literals are actually stored as (read-only) arrays of the number of character in the string plus one for the string terminator.

此外,为了帮助您理解为什么*pp[0]相同的原因,您需要知道对于任何指针或数组 p和有效索引i,表达式p[i]等于*(p + i).要获得第一个字符,您必须具有索引0,这意味着您具有p[0],然后应等于*(p + 0).向任何事物添加零是无操作的,因此*(p + 0)*(p)相同,而*(p)*p相同.因此p[0]等于*p.

Also, to help you understand why *p is the same as p[0] you need to know that for any pointer or array p and valid index i, the expressions p[i] is equal to *(p + i). To get the first character, you have index 0, which means you have p[0] which then should be equal to *(p + 0). Adding zero to anything is a no-op, so *(p + 0) is the same as *(p) which is the same as *p. Therefore p[0] is equal to *p.

关于您的编辑(在其中执行printf(*p)),由于*p返回由p指向的第一个元素"(即p[0])的值,因此您要传递单个字符作为格式字符串的指针.这将导致编译器将其转换为指针,该指针指向具有该单个字符值的任何地址(它不会将字符转换为指针的指针).此地址不是一个非常有效的地址(在 ASCII字母 'a'具有值97是程序将在其中查找要打印的字符串的地址),您将具有未定义的行为.

Regarding your edit (where you do printf(*p)), since *p returns the value of the first "element" pointed to by p (i.e. p[0]) you are passing a single character as the pointer to the format string. This will lead the compiler to convert it to a pointer which is pointing to whatever address has the value of that single character (it doesn't convert the character to a pointer to the character). This address is not a very valid address (in the ASCII alphabet 'a' has the value 97 which is the address where the program will look for the string to print) and you will have undefined behavior.

这篇关于字符指针和printf函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆