Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指向整数数组的字符指针_C - Fatal编程技术网

C 指向整数数组的字符指针

C 指向整数数组的字符指针,c,C,我在代码块中运行代码,它将0作为输出。 如果我把p改为int指针,那么它的输出是2 int main() { int x[] = {1, 2, 3}; char *p = &x; printf("%d", *(p+1)); return 0; } 为什么会这样?当你增加一个指针时,它会根据它指向的对象的大小移动 假设你有16位整数。在二进制中,数字1是:0000 0001 char指针一次只能指向8位:0000 0000当p被声明为char指针时,它应该

我在代码块中运行代码,它将0作为输出。 如果我把p改为int指针,那么它的输出是2

int main()
{
    int x[] = {1, 2, 3};
    char *p = &x;
    printf("%d", *(p+1));
    return 0;
}

为什么会这样?

当你增加一个指针时,它会根据它指向的对象的大小移动

假设你有16位整数。在二进制中,数字1是:0000 0001

char指针一次只能指向8位:0000 0000

当p被声明为char指针时,它应该指向大小为1字节的数据。因此p+1将p增加1字节

由于int至少有4个字节长,因此p+1可能指向1的高阶字节中的第二个,仍然是0

如果您希望它有相同的输出,您可以这样做

int main() 
{    
int x[] = {1, 2, 3}; 
    int *p = &x; 
    printf("%d", *(p+1));
    return 0;
}

但最好避免使用此类代码,并使用-Wall标志编译,这在您的情况下肯定会产生警告。

要从稍微不同的角度看二进制+运算符,C99标准第6.5.6章第8段说,[强调我的]

将整数类型的表达式添加到指针或从指针中减去时,结果的类型为指针操作数。如果指针操作数指向数组对象的某个元素,且数组足够大,则结果将指向与原始元素偏移的元素,从而使结果数组元素和原始数组元素的下标之差等于整数表达式。换句话说,如果表达式P指向数组对象的第i个元素,则表达式P+N、N+P和 P-N,其中N的值N分别指向i+N-th和i−数组对象的第n个元素,前提是它们存在

因此,在第一种情况下,p是char*类型,p+1作为指针给出一个结果,该指针由sizeofchar递增[大多数情况下为1字节],因此指向p持有的char数组的第二个元素。因为实际上,p所持有的数组是int类型的[32位系统中长度为4字节],所以根据存储的值,[1被存储为0000 0001],*p+1打印出0


OTOH,在第二种情况下,p是int*类型,p+1给出一个结果作为指针,该指针由sizeofint递增,因此指向p持有的int数组的第二个元素。因为实际上,p持有的数组是int类型的,所以根据存储的值,[intx[]={1,2,3};],*p+1打印出2。

假设sizeofint是16位。二进制中的2是00000000000010。 sizeofchar是8位。 Little和big-endian是存储多字节数据类型的两种方法

考虑以下代码: int i=2; char c=char&i; 如果*c==2 印刷字体; else//如果*c为0 printfBig-endian

从这段代码可以得出结论,Big-Endian将把2存储为00000000000010。但Little Endian会将其存储为000000 100000000,所以输出为零意味着前8位为零,所以系统是Big-Endian。若它使用小尾端,答案将是2,因为字符p应该只指向8位。 实际上,声明指针的数据类型意味着指定您希望它引用多少位以及递增时它将跳转多少位。 如果在本例中,由于p是一个字符指针,*p+1将在Big-endian中引用00000010,在Little-endian中引用00000000。 您的编译器可能使用32位的整数,所以我认为在这两种情况下*p+1都会给出0。as 2=>00000000000000000000000000000010从任一侧开始的第二个字节为0

提到这一点:`包括

printf("%d\n", *(p + sizeof(int)));
输出: 1. 0 0 0 2. 0 0
3

因为int不是charp+1,所以第二个程序中的int与第一个程序中的p+4相同。这是因为sizeofchar是1字节,sizeofint是4字节。char*p=&x;是一种违反约束的行为-请注意编译器错误消息为准确起见,可能存在的重复:字符指针一次只能指向字符位。字符位被定义为至少8。@MattMcNabb谢谢,我更正了我的帖子,不再叫我Shirley了,因为指针p包含x的地址,而x本身包含第一个元素的地址,那么为什么不*p是存储在x中的第一个元素的打印地址?它是第一个元素的打印值。当你使用*Y时,你指的是地址的内容,即指针指向的地址的值。这就是为什么它要打印值。删除*并改用%p格式打印地址。
       int main()
      {
        int x[] = {1, 2, 3};
         char *p = &x;
        printf("%d\n", *p);
         printf("%d\n", *(p+1));
          printf("%d\n", *(p+2));
          printf("%d\n", *(p+3));
         printf("%d\n", *(p+4));
          printf("%d\n", *(p+5));
         printf("%d\n", *(p+6));
         printf("%d\n", *(p+7));
          printf("%d\n", *(p+8));
          return 0;
            }`