关于C语言指针和指针大小的一些基本问题

  • 本文关键字:指针 问题 语言 关于 c
  • 更新时间 :
  • 英文 :


在下面使用这个在线编译器的C代码中,当我将指针地址增加1时,实际地址增加4。这是因为数据类型是int。

#include <stdio.h>
int main()
{
int my_array[3] = {0, 1, 2};
int* p_array = my_array;

printf("%p n", p_array);

p_array = ++p_array;

printf("%p n", p_array);
return 0;
}

编译后输出:

0x7ffeb9ba5814 
0x7ffeb9ba5818

我有两个问题:

  1. 是否可以使用指针直接访问/指向地址0x7ffeb9ba5815的单个字节?(不使用按位操作)

  2. 在上述情况下,地址指针如何保持为6字节,如0x7ffeb9ba5818?(虽然地址是4或8字节)

首先,我假设你指的是++p_array而不是p_array = ++p_array,因为那是未定义的行为。

  1. 是的,它是。将指针转换为(char*)类型(如果使用GCC,也可以转换为(void*)类型),该指针将随着1的步长增加或减少:
int *a = 0;
a++; // a is now 4
char *b = (char*) a;
b++; // b is now 5
  1. 它们实际上是8个字节,但前两个字节是零。当打印出来时,它们会被格式化成尽可能少的数字,同样的,当你写数字200时,你不会写0000200这样的东西。
  1. 是的,例如,您可以将地址转换为指向-char的指针(在C中是字节的同义词!)并访问:

    char *cp = (char *) p_array;
    cp++;
    printf("%pn", (void *) cp);
    
  2. 它们不是6字节;打印地址只是省略了前导零,就像打印十进制的123一样,而不是0…0000000123。实际上,在第一种情况下,指针的值应该是0x00007ffeb9ba5814

如果你有一个指向T类型对象的指针,在该指针上加1就得到该类型下一个对象的地址。例如,假设如下声明:

char *cp  = (char *)  0x8000;
short *sp = (short *) 0x8000;
long *lp  = (long *)  0x8000;

则下列语句都为真:

Address    char           short         long
–––––––    +–––+          +–––+         +–––+
0x8000     |   | cp       |   | sp      |   | lp
+–––+          + – +         + - +
0x8001     |   | cp + 1   |   |         |   |
+–––+          +–––+         + - +
0x8002     |   | cp + 2   |   | sp + 1  |   |
+–––+          + - +         + - +
0x8003     |   | cp + 3   |   |         |   |
+–––+          +–––+         +–––+
0x8004     |   | cp + 4   |   | sp + 2  |   | lp + 1
+–––+          + - +         + - +
...            ...           ...

是否可以使用指针直接访问/指向地址0x7ffeb9ba5815的单个字节?(不使用按位操作)

是-将其强制转换为char *unsigned char *:

unsigned char *ucp = ((unsigned char *) my_array + 1);

在上述情况下,地址指针如何保持为6字节,如0x7ffeb9ba5818?(虽然地址是4或8字节)

%p转换说明符只是不打印任何前导0 -实际值是0x00007ffeb9ba5818

如0x7ffeb9ba5818?

这是一个48位的虚拟地址区域。就在中间下面。比如491/1000。

printf("%p %p %p %p %p %p %pn",
0, 1, 16, 255, -1, -1L, (1L<<48)/2-1);

打印:

(nil) 0x1 0x10 0xff 0xffffffff 0xffffffffffffffff 0x7fffffffffff

不仅前导零被抑制!也是0本身

0x7fffffffffff为140tb。虚拟.

对于下一个分页级别(5),您将看到更少的前导零。

最新更新