C语言清楚了解指针的使用
作者:JDSZGLLL
前言
经过了指针的初步学习,我们了解了指针有以下特点:
1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。
3. 指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。
今天将要从各种不同的指针的角度切入,使得我们对指针的了解更加深入。
字符指针
我们现在已经学会下面的这种指针的使用了:
int main() { char ch = 'w'; char* pc = &ch; *pc = 'w'; return 0; }
通过这段代码,把字符变量ch的地址赋给了pc,同时pc的类型是char*。
接下来让我们来看一看另一段代码:
int main() { const char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗? printf("%s\n", pstr); return 0; }
我们看到,这里是把一个字符串常量和指针pstr关联起来了。并且无论有没有加const,常量的内容是不能改变的。
int main() { char* pstr = "hello bit.";//这里是把一个字符串放到pstr指针变量里了吗? *pstr = 'w'; printf("%s\n", pstr); return 0; }
当我们如上图代码一样,试图改变常量字符串时就会报错:
让我们来通过下面的代码了解内部的逻辑:
int main() { char str1[] = "hello world."; char str2[] = "hello world."; const char *str3 = "hello world."; const char *str4 = "hello world."; if(str1 ==str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if(str3 ==str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n"); return 0; }
根据代码和运行结果,我们可以知道指针指向的常量字符串的地址是相同的,但把字符串赋予数组时,地址不同,让我们用图来描述这个过程。
同时str1,str2,str3,str4,指的都是字符串首字符的地址。
指针数组
指针数组的本质是数组,只是在数组中存放的内容是指针变量。
接下来让我们看看指针数组长什么样:
int* arr1[10]; //整形指针的数组 char *arr2[4]; //一级字符指针的数组 char **arr3[5];//二级字符指针的数组
指针数组可以类比普通数组,比如:
我们可以发现,指针数组和普通数组的区别仅仅是数组中储存的元素类型不一样,所以说指针数组本质上还是数组。
数组指针
说完了指针数组,让我们来了解一下数组指针 ,数组指针本质上是一个指针。接下来让我们类比一下数组指针和我们常见的指针:
让我们通过一段代码来深入了解 数组指针的特点:
int main() { int arr[10] = { 0 }; printf("arr = %p\n", arr); printf("&arr= %p\n", &arr); printf("arr+1 = %p\n", arr + 1); printf("&arr+1= %p\n", &arr + 1); return 0; }
通过学习我们知道arr是数组首元素的地址,&arr是整个数组的地址,可类比为普通指针和数组指针。
函数指针
函数指针就是存放函数地址的指针 ,通过函数指针可以调用相应的函数。
void test() { printf("hehe\n"); } int main() { printf("%p\n", test); printf("%p\n", &test); return 0; }
通过这段代码我们了解到,函数是有地址的,那怎么把这个地址赋予指针呢?
void test() { printf("hehe\n"); } int main() { printf("%p\n", test); printf("%p\n", &test); void (*p)() = test; (*p)(); return 0; }
以上代码让我们知道了,函数是可以通过指针调用的。
到此这篇关于C语言清楚了解指针的使用的文章就介绍到这了,更多相关C语言指针内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!