简体   繁体   English

C编程指针

[英]C Programming Pointers

I don't understand why is the last code block generating 1819043176 1870078063 6581362 0 1 2 3 4 0 6488159... These numbers are not random, but why those numbers? 我不明白为什么最后一个代码块生成1819043176 1870078063 6581362 0 1 2 3 4 0 6488159 ...这些数字不是随机的,但是为什么这些数字呢? Thank you! 谢谢!

int main(void) {
    int x;
    int y[10];
    int* p;
    char* q;
    int k;
    char* prefix;

    k = 0;
    while (k < 10) {
            y[k] = k;
            k = k + 1;
    }
    x = 42;
    printf("address of y are %d %d %d\n", y, y + 1, y + 9);
    doit(y + 1);

    p = &y[0];
    printf("p is %d\n", p);
    *p = 42;
    p = p + 9;
    printf("p is %d\n", p);
    *p = 17;

    q = "hello world";
    p = "hello world";
    k = 0;
    while (k < 10) {
            printf("%d ", q[k]);
            k = k + 1;
    }
    printf("The end\n");

    k = 0;
    while (k < 10) {
            printf("%d ", p[k]);
            k = k + 1;
    }
    printf("The end\n");
}

doit

void doit(int p[9])
{
    char* prefix = "";
    int k = 0;
    printf("p is %d at address %d\n", p, &p);
    while (k < 10)
    {
        printf("%s%d", prefix, *p);
        prefix = ", ";
        k = k + 1;
        p = p + 1;
    }
    printf("\n");
}

1819043176 is 6C6C6568 in hexadecimal, which is stored as the bytes 68, 65, 6c, 6c on a little-endian machine. 1819043176是十六进制的6C6C6568,将其作为字节68、65、6c,6c存储在小字节序机器上。 These are the first four characters of "hello world". 这是“ hello world”的前四个字符。 And so on. 等等。

Normally you are not supposed to do these things in C, the results are undefined or implementation-dependent. 通常,您不应该在C中执行这些操作,结果是不确定的或与实现有关的。

If you nevertheless want to peek around in memory then better do it in a more systematical way, for example write a small utility to do a hex dump. 但是,如果您仍然想在内存中窥视一下,那么最好以更系统的方式进行操作,例如编写一个小的实用程序来进行十六进制转储。

I'm not digging enough to give you the answer, but I do have an important suggestion: crank up your compiler's warnings. 我没有为您提供足够的答案,但是我有一个重要建议: 加快编译器的警告。 When my bash starts up, it aliases gcc to /usr/bin/gcc -Wall -Wextra -Werror so that anything I try to compile has to pass through some of GCC's harshest tests (and it treats all warnings as errors, so minor mistakes won't compile). 当我的bash启动时,它将gcc别名为/usr/bin/gcc -Wall -Wextra -Werror这样,我尝试编译的任何内容都必须通过GCC的最严格的测试(并且将所有警告均视为错误,因此是小错误)将无法编译)。 Your code gave me an error printout a mile long (not literally). 您的代码给了我一英里长的错误打印输出(不是字面上的意思)。 Some errors: 一些错误:

  • printf() has a special format specifier for pointers: %p . printf()有一个特殊的指针格式说明符: %p Don't use %d - that's for int s. 不要使用%d这是用于int的。
  • p is an int * (pointer to an int ), "hello world" is a char * . p是一个int * (指针到一个int ), "hello world"是一个char * You can assign one to another, but it's usually a bad idea, so if you really want to do it, you should use a cast to say "Hey, I meant to do this:" p = (int *) "hello world"; 您可以将一个分配给另一个,但这通常不是一个好主意,因此,如果您确实想这样做,则应该使用强制转换说“嘿,我的意思是这样做:” p = (int *) "hello world";
  • main() doesn't return void , it returns an int . main()不返回void ,它返回一个int You know this, because you declared int main(void) like a good programmer, but then we get to the end of main() and there's no return statement! 您知道这一点,因为您像一个好的程序员一样声明了int main(void) ,但随后我们到了main()的结尾,没有return语句! How is it supposed to return an int if you don't return anything? 如果您不return任何内容,应该如何返回int In C++, we can skip the ending return statement, but not in C (at least, we really shouldn't, because bad things can happen). 在C ++中,我们可以跳过结尾的return语句,但是在C语言中则不能(至少,我们确实不应该这样做,因为可能会发生不好的事情)。

Also, you have a pattern that you repeat often: 另外,您有一个经常重复的模式:

k = 0;
while (k < 10) {
        y[k] = k;
        k = k + 1;
}

Welcome to for loops: 欢迎使用for循环:

for(k = 0; k < 10; k++) {
        y[k] = k;
}

for() loops have three parts: for()循环包含三个部分:

for(init; cond; inc)

init is run once before the loop, then the loop executes as long as cond is true, executing inc at the end of every loop. init在循环之前运行一次,然后只要cond为true,循环就会执行,并在每个循环结束时执行inc It is almost exactly equivalent to what you're doing, and is more concise. 它几乎完全等同于您正在做的事情,并且更加简洁。

you have p pointing to the string "hello world" 您有p指向字符串“ hello world”
but you have defined p as a pointer to integers, so p looks like this 但您已将p定义为指向整数的指针,因此p看起来像这样

p[0] = 'hell'
p[1] = 'o wo'
p[2] = 'rldx'
p[3] = 'xxxx'
p[4] = 'xxxx'
p[5] = 'xxxx'
p[6] = 'xxxx'
p[7] = 'xxxx'
p[8] = 'xxxx'
p[9] = 'xxxx'

where xxxx means you have not set this memory to anything.

lets look at p[0]
h=0x68
e=0x65
l=0x6c
l=0x6c

so you have the hexidecimal number 0x6c6c6568 which you can check is 1819043176

and so on

The reason that (a) you're getting numbers printed and (b) that the numbers aren't random is because in the last code block, you're trying to print a string as decimals. (a)打印数字和(b)数字不是随机的原因是因为在最后一个代码块中,您试图将字符串打印为小数。 After all, that's what %d expects to print - a decimal. 毕竟,这就是%d期望打印的内容-小数。 That's not got anything to do with pointers. 这与指针没有任何关系。

You don't say what output you're expecting, but you have to chose the correct formatter to do that. 您没有说期望输出什么,但是您必须选择正确的格式化程序来实现。

Another suggestion - the normal idiom for incrementing a variable in C and C++ is 另一个建议-在C和C ++中增加变量的通常习惯用法是

++x;

or 要么

x++;

to increment a value by 1 and 将值增加1并

x += 9;

to increment it by more than 1 (obviously 9 in this case). 将其增加1以上(在这种情况下,显然是9)。

I think it's because you are passing a char to printf when the format string is expecting an integer. 我认为这是因为当格式字符串期望整数时,您正在将char传递给printf。 Try casting q[k] and p[k] to integers. 尝试将q [k]和p [k]转换为整数。

while (k < 10) {
        printf("%d ", (int)p[k]);
        k = k + 1;
}

The call to printf() is not a normal function call, it uses varargs/stdargs and in those, the function needs to unpack the correct type. 对printf()的调用不是正常的函数调用,它使用varargs / stdargs,在这些函数中,该函数需要解压缩正确的类型。

So the first number in your output, 1819043176, corresponds to 0x6C6C6568. 因此,输出中的第一个数字1819043176对应于0x6C6C6568。 See how the character value for the lowercase 'h' (0x68) that you were presumably expecting to see is the least significant byte in four-byte integer? 看看您大概希望看到的小写字母'h'(0x68)的字符值如何是四字节整数中的最低有效字节? This is because the varargs routines were expecting an integer-sized argument because of the %d format specifier. 这是因为varargs例程由于%d格式说明符而期望使用整数大小的参数。

This doesn't do what you think it does (I hope, maybe): 这并没有按照您的想法做(我希望,也许):

while (k < 10) {
        printf("%d ", q[k]);
        k = k + 1;
}

Think about what q is, what printf does, and what %d means (hint, look at the assignment of q). 考虑一下q是什么,printf做什么,以及%d的含义(提示,看一下q的赋值)。 I would also suggest including the output of what you expect as a result because it's not obvious from the code what you're actually trying to accomplish (other than printing out pointers to ints using printf instead of ints). 我还建议您包含期望结果的输出,因为从代码中您实际要完成的目标并不明显(除了使用printf而不是int打印指向int的指针外)。

Your problem is about the variable p. 您的问题与变量p有关。 it is int *, and sizeof an integer variable is 4 byte (it may change according to system and compiler) but the sizeof (char) is 1 byte 它是int *,整数变量的sizeof是4个字节(可能会因系统和编译器而异),但是sizeof(char)是1个字节

"hello world" string is 12 byte -with null- 12 byte can be defined in 3 integer. “ hello world”字符串为12个字节-带空值-可以3个整数定义12个字节。

after this line 在这行之后

p = "hello world";

only 3*4 memory of p will be used. p仅使用3 * 4内存。 (*p points array "y") Rest of them will be null... (* p点数组“ y”)其余的将为null ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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