今天写一个C语言程序,然后发现指针有问题,找不到原因,就抽离出程序逻辑写了一个简单的代码,然后发现C语言指针我竟然还有这么多盲点,记录一下。
首先抽离源程序逻辑写了一个荒唐的测试代码:
1 2 3 4 5 6 7 8 9 10 11 |
#include <stdio.h> int main() { int a = 2; int *b = 3; int *c; c = 3; printf("%d, %d, %d, %d\n", a, b, c, *c); return 0; } |
程序报了一堆错误,之所以写了这么一个程序,是因为前面我在测试的时候写了下面两段代码结果会不一样:
1 2 3 4 5 6 7 |
# 代码1,没有报错,并且输出a = 1 int* a = 1; # 代码2,运行时错误 int* a; *a = 1; |
这个个代码的想法是声明指针a,在指向的位置存放1。后面发现这种写法非常错误,主要有两点:第一是指针变量和普通变量有区别(声明和使用的时候形式有差异),在这里int* a = 1
这种初始化应该是给一个int类型的指针值,而不是给一个int类型值;第二是使用指针的时候一定要给该指针先分配内存空间,否则不知道该指针指向哪儿,就会引发严重的错误,第二段代码就是指针a没有分配空间就访问。对于第一段代码,感觉编译器直接这句声明等效成了int a = 1,估计这可能是编译器的自动优化。
于是根据上面问题重写把上面的那段荒唐的代码重新改写:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> #include <malloc.h> int main() { int a = 2; int *b = malloc(sizeof(int)); int *c = b; *c = 3; printf("%d, %d, %d, %d\n", a, *b, c, *c); free(b); return 0; } |
这一次程序按照预期的结果执行,对于指针b使用malloc函数分配空间初始化(对应后面记得free,不然大程序可能会内存爆炸);对于指针c使用指针b初始化,这样其实b和c都指向同一个地址。
另外在给指针赋值的时候,一定注意指针的类型:
1 2 3 4 |
int* p; p = 0x1111111; //这种肯定是错误的 p = (int*)0x1111111; //给指针赋值要加上类型强制转换 |
给指针指定类型是很有必要的,因为指针只是指向首地址,类型决定数据在内存的尾地址,首尾地址才能确定指定类型的数据再内存中的存储位置。
所以,以后对于指针使用之前一定要先分配内存空间或者指向已经分配的内存空间,不再使用的指针要及时释放;指针使用过程中时刻注意指针类型。
https://bbs.linmao.dev/?thread-4.htm
之前也遇到过这个问题,但是当时没有理解清楚,现在比当初理解的更深刻一点。