C中空指针的指针算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C中空指针的指针算法相关的知识,希望对你有一定的参考价值。
当指向特定类型(例如int
,char
,float
,..)的指针递增时,其值将增加该数据类型的大小。如果指向大小为void
的数据的x
指针递增,那么如何指向前面的x
字节?编译器如何知道将x
添加到指针的值?
最后的结论:void*
上的算法在C和C ++中都是非法的。
GCC允许它作为扩展,请参阅Arithmetic on void
- and Function-Pointers(请注意,本节是本手册“C扩展”一章的一部分)。为了与GCC兼容,Clang和ICC可能允许void*
算术。其他编译器(如MSVC)不允许对void*
进行算术运算,如果指定了-pedantic-errors
标志,或者指定了-Werror-pointer-arith
标志,则GCC不允许运算(如果您的代码库也必须使用MSVC编译,则此标志很有用)。
C标准发言
报价取自n1256草案。
标准对添加操作的描述说明:
6.5.6-2:另外,两个操作数都应具有算术类型,或者一个操作数应为指向对象类型的指针,另一个操作数应为整数类型。
因此,这里的问题是void*
是否是指向“对象类型”的指针,或者等效地,void
是否是“对象类型”。 “对象类型”的定义是:
6.2.5.1:类型被划分为对象类型(完全描述对象的类型),函数类型(描述函数的类型)和不完整类型(描述对象但缺少确定其大小所需信息的类型)。
该标准将void
定义为:
6.2.5-19:
void
类型包含一组空值;它是一种不完整的类型,无法完成。
由于void
是一个不完整的类型,它不是一个对象类型。因此,它不是加法运算的有效操作数。
因此,您无法对void
指针执行指针运算。
笔记
最初,人们认为允许void*
算术,因为C标准的这些部分:
6.2.5-27:指向void的指针应具有与指向字符类型的指针相同的表示和对齐要求。
然而,
相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员。
所以这意味着printf("%s", x)
具有相同的含义x
是否具有char*
或void*
类型,但这并不意味着你可以对void*
进行算术运算。
编者注:本答案已经过编辑,以反映最终结论。
void*
指针不允许指针运算。
将它转换为char指针,将指针向前转x字节。
你不能在void *
类型上做指针算术,正是因为这个原因!
C标准不允许void指针算术。但是,考虑到void的大小是1
,允许GNU C.
C11标准§6.2.5
第 - 19段
void
类型包含一组空值;它是一个不完整的对象类型,无法完成。
以下程序在GCC编译器中正常工作。
#include<stdio.h>
int main()
{
int arr[2] = {1, 2};
void *ptr = &arr;
ptr = ptr + sizeof(int);
printf("%d
", *(int *)ptr);
return 0;
}
可能是其他编译器生成错误。
在进行指针运算之前,必须将其强制转换为其他类型的指针。
无效指针可以指向任何内存块。因此,当我们在void指针上尝试指针运算时,编译器不知道要递增/递减多少字节。因此,void指针必须首先被类型转换为已知类型,然后才能涉及任何指针算法。
void *p = malloc(sizeof(char)*10);
p++; //compiler does how many where to pint the pointer after this increment operation
char * c = (char *)p;
c++; // compiler will increment the c by 1, since size of char is 1 byte.
编译器通过类型转换知道。鉴于void *x
:
x+1
向x
添加一个字节,指针转到字节x+1
(int*)x+1
添加sizeof(int)
字节,指针转到字节x + sizeof(int)
(float*)x+1
addressizeof(float)
bytes等
虽然第一项是不可移植的并且违反了C / C ++的Galateo,但它仍然是C语言正确的,这意味着它将编译成大多数编译器的东西,可能需要一个合适的标志(如-Wpointer-arith)
以上是关于C中空指针的指针算法的主要内容,如果未能解决你的问题,请参考以下文章
[SSM+layui]汽车出租系统06_加载左侧菜单(角色里面 type为1的就是超级管理员(这里)简单json如何转变成标准json)List和ArrayList的区别项目中空指针错误怎么解决(代码