我一直在努力理解为什么改变指针的类型是无效的。我在一些地方问过改变类型是无效的,所以我测试了一些代码:
第一个代码:
int *x;
int y = 35;
x = &y;
printf("%c\n", *x);
字符串
第二个代码:
char *x;
int y = 35;
x = &y;
printf("%c\n", *x);
型
我得到的代码告诉我不要改变指针类型:
第三个代码:
void* vp = malloc(100);
cp = (char*)vp;
for (; *cp != '\0'; cp++)
{
printf("%c", *cp);
}
printf("\n\n");
numbytes = (sizeof(numbers) / sizeof(numbers[0])) * sizeof(int);
memcpy(vp, numbers, numbytes);
ip = (int*)vp;
for (; *ip != -1; ip++)
{
printf("%d, ", *ip);
}
printf("\n\n");
printf("vp = %p\n", vp);
}
型
我的实际问题是,我被告知不改变指针的类型。而在第三个例子中,它被改变了2次,从void到char到int。在我的第一个和第二个例子中,我也改变了类型,但它是无效的。我不知道为什么。在第三个例子中,它加载了一些值,然后改变了指针的类型。在我的第一个和第二个我也加载了值,并将指针从int改为float。但它是无效的。
什么时候可以改变类型,什么时候不能?我知道int指针可以指向char,但是例如int* x = &(char)y;使用 *x总是返回int值,但是键入(printf(“%c”,x))将返回一个字符,就好像它忽略了指针的类型:>
我什么时候可以换类型?
这里是另一个第四个例子,我把int 指针变成了一个浮点数,其中已经包含了int值,结果是浮点数总是0。
int *x;
int y = 5;
x = &y;
printf("%f\n", *(float*)x);
型
我试着理解什么时候可以改变指针的类型,什么时候不能。由于malloc类型和指针后面的类型(如int x =(float)y)没有太大关系,这里y旁边的float也没有太大关系,因为算术是基于“x”类型的。虽然它可能会影响结果 *x将显示,因为float有不同的字节分配。
除此之外,我对“类型”什么时候重要以及当它包含值时什么时候可以更改它感到困惑。
2条答案
按热度按时间s6fujrry1#
给予这个机会.
第一个月(以及
calloc()
和realloc()
)将,如果没有问题,“咬掉”一块足够大的 * 堆存储 * 来存储所请求的字节,并对齐以存储语言的最大数据类型(类似于8字节的double
)。分配例程被要求提供一定数量的字节,并返回void *
,以便程序按照自己的意愿使用这些字节。C语言允许将
void
指针(一个地址)转换为指向任何其他数据类型的指针(不严格地说),因此malloc()
返回void *
。调用函数(通常)将该指针存储到指针变量中,该指针变量的类型满足函数的需要。例如:
int *ptrInt = malloc( 10 * sizeof *ptrInt );
分配空间以存储10个整数值。这一点你明白。你可以在10个整数的沙箱中玩得尽可能多,然后free( ptrInt );
所有的数据库都是字节的集合。
char
是一个字节,double
是8个字节。对齐和解释是至关重要的!如果你想探索,你可以 * 重新解释 * 一个地址:字符串
这类东西在错误的人手中充满了危险(比如没有经验的程序员)。通过 * 强制转换 * 到错误的类型,编译器提供的保护(警告,错误)被抑制了。程序员已经承担了责任,并将承担任何后果(比如超出声明为受程序代码控制的内存范围)。
一种好的类型转换是用来避免令人讨厌的意外(比如当
signed char
作为函数的参数提升为int
时,它被 * 符号扩展 *)。型
一般来说,苹果就是苹果,橘子就是橘子,直到你对数据在语言(和内存)中的表示方式有了足够的理解,坚持简单的东西,不要不恰当地使用类型转换。
编译器是你的朋友,它希望你写出好的代码来供它咀嚼。像对待其他朋友一样注意它的警告。当你学会理解它的批评并纠正代码中的批评时,你将是受益者!
t98cgbkg2#
通过其他类型指针调用未定义的行为,因为它违反了严格的alising规则,除了:
1.当您通过指向相同或兼容类型的指针访问对象时,
1.当你使用指向
char
的指针访问一个对象时1.当你用一个空指针分配一个指针,
malloc
家族函数分配的对象的引用。numbers
的定义。如果它是int
数组,则它是正确的float
的指针访问int
对象