(一)什么是指针指针就是存放变量内存地址的变量 怎么理解呢我们电脑的内存分为8GB,16GB,32GB等等而内存也被划分成一个个的内存单元每个内存单元的大小取一个字节每个内存单元就相当于一个学生宿舍一个字节空间里又能放8个比特位就像我们宿舍是8人间每个人是一个比特位每个内存单元都有一个编号就相当于宿舍的门牌号而这个编号就等于地址等于指针(二)取地址操作符在c语言中创建变量本质上就是向内存申请空间比如创建一个整型变量如下int a10;一个整型变量占4个字节就是向内存申请了4个字节每个字节都有自己的地址如下所示那么如何取到a的地址呢这里我们就在需要用到取地址操作符在之前使用scanf函数也是经常用到表示取这个数据的地址 怎么将地址打印出来呢这里需要用到之前学到的占位符%p比如将上述整形a的地址打印出来如下所示#include stdio.h int main() { int a10; a;//取出a的地址 printf(%p,a); return 0; }这里整型a明明占了4个字节为什么只打印出来一个地址因为a取出的是4个字节中地址较小的字节的地址(三)指针变量的创建和类型在上述过程中我们得到了a的地址那么为了后续使用怎么样将它存储起来这时候我们就可以将它存储在指针变量中 如下所示int a 10; int* pa a;//取出a的地址将其放入指针变量pa中那么上述代码中的指针变量类型是什么首先pa左边的int*它在常规的整型变量中加了一个*而*就表示pa是指针变量而前面的int指pa指向的a是一个整型类型 那如果有一个char类型的b那么该如何创建指针变量呢如下所示char ba; char*pcb;//取出字符b的地址将其放入指针变量pc中(四)指针变量的使用我们通过指针变量将地址给存储起来那么又该如何使用呢 这时候我们就需要用到解引用操作符*具体操作如下所示int a 10; int* pa a; *pa;//解引用通过pa中存放的地址找到指向的空间所以这里的*pa就相当于a printf(%d, *pa);打印出来的*pa就是a的值也可以通过修改*pa的值来修改a的值如下所示可以看出不仅*pa的值变成199a的值也同样修改为199(五)指针变量类型的意义1.指针的解引用下面我们通过两段代码来理解指针变量的意义int a 0x11223344;//整型a存放的是16进制的数字 int* pa a; * pa 0;将整型a的4个字节改成0原来a在内存中存放的值如下修改完之后如下可以看出将4个字节全部修改成0然而当我们创建char类型的变量时int a 0x11223344; char* pa (char*) a; * pa 0;可以看出只能将a的第一个字节改成0所以指针的类型决定了指针解引用时的权限char*类型就只能访问一个字节而int*类型的指针就可以访问4个字节2.指针-整数通过上述的例子我们可以得知指针类型的不同访问的字节也不同我们可以再举一例如下方代码int a 10; int* pa a; char* pc (char*)a; printf(a%p\n, a); printf(pa%p\n, pa); printf(pa1%p\n, pa1); printf(pc%p\n, pc); printf(pc1%p\n, pc1);我们可以看出char类型的指针1之后在原来的基础上地址只变化了一位而int类型的指针1之后则在原来的基础上变化了4位所以可以得知指针的类型决定了指针变化了多少位。那么我们可以再做个练习用指针将数组中的元素依次打印出来如下代码所示int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int sz sizeof(arr) / sizeof(arr[0]); int i 0; int* pa arr[0]; for (i 0; i sz; i) { printf(%d , *(pa i)); }pa表示的是取的是arr数组中第一个元素的地址那我们只需要依次求出arr数组中元素的地址再使用解引用符号*我们就可以依次得出arr数组中的元素3.指针-指针用以下代码举例int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int* pa arr[0]; int* pc arr[9]; printf(%d, pc-pa);指针-指针最终得到的结果就是两个指针(地址)之间的元素个数⚠️:指针-指针必须指向的是同一内存空间像上方的代码中指向的都是arr数组下方代码为错误示范int arr[4] { 1,2,3,4 }; char b e; int* pa arr[2]; char* pc b; printf(%d, pc - pa);我们可以用指针-指针来求字符串长度在之前不用指针如何求字符串长度的呢我们需要用到strlen函数并且strlen函数的返回值是size_t且需要头文件string.h如下所示#include stdio.h #include string.h int main() { char ch[] abcde; size_t len strlen(ch); printf(%d, len); return 0; }那么我们现在知道指针-指针就是两个指针之间的元素个数那么我们可以分别求出字符串长度中第一个元素的地址和’/0’的地址将两个指针(地址)相减就能得到字符串长度了如下代码所示size_t my_strlen(char* p)//指针接受参数 { char* start p[0];//start取ch数组第一个元素的地址 while (*p ! \0) { p; } //p最终变成\0的地址 return p - start; } int main() { char ch[] abcde; size_t len my_strlen(ch);//函数传递的是ch数组其实ch又代表ch数组中第一个元素的地址 printf(%d, len); //所以传递的是地址需要用指针来接受参数 return 0; }4.指针的关系运算两个指针比较大小我们依旧拿我们最熟悉的题目举例打印出数组中的每个元素如下代码所示int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int sz sizeof(arr) / sizeof(arr[0]); int* pa arr; int* pc arr[sz]; while (pa pc) { printf(%d , *pa); pa; } return 0; }上述代码中pa表示第一个元素的地址而pc表示数组中的第十个元素的后一位的地址不是数组内的所以当papc时解引用打印出元素再通过pa依次打印后面的元素
深入理解指针---1
(一)什么是指针指针就是存放变量内存地址的变量 怎么理解呢我们电脑的内存分为8GB,16GB,32GB等等而内存也被划分成一个个的内存单元每个内存单元的大小取一个字节每个内存单元就相当于一个学生宿舍一个字节空间里又能放8个比特位就像我们宿舍是8人间每个人是一个比特位每个内存单元都有一个编号就相当于宿舍的门牌号而这个编号就等于地址等于指针(二)取地址操作符在c语言中创建变量本质上就是向内存申请空间比如创建一个整型变量如下int a10;一个整型变量占4个字节就是向内存申请了4个字节每个字节都有自己的地址如下所示那么如何取到a的地址呢这里我们就在需要用到取地址操作符在之前使用scanf函数也是经常用到表示取这个数据的地址 怎么将地址打印出来呢这里需要用到之前学到的占位符%p比如将上述整形a的地址打印出来如下所示#include stdio.h int main() { int a10; a;//取出a的地址 printf(%p,a); return 0; }这里整型a明明占了4个字节为什么只打印出来一个地址因为a取出的是4个字节中地址较小的字节的地址(三)指针变量的创建和类型在上述过程中我们得到了a的地址那么为了后续使用怎么样将它存储起来这时候我们就可以将它存储在指针变量中 如下所示int a 10; int* pa a;//取出a的地址将其放入指针变量pa中那么上述代码中的指针变量类型是什么首先pa左边的int*它在常规的整型变量中加了一个*而*就表示pa是指针变量而前面的int指pa指向的a是一个整型类型 那如果有一个char类型的b那么该如何创建指针变量呢如下所示char ba; char*pcb;//取出字符b的地址将其放入指针变量pc中(四)指针变量的使用我们通过指针变量将地址给存储起来那么又该如何使用呢 这时候我们就需要用到解引用操作符*具体操作如下所示int a 10; int* pa a; *pa;//解引用通过pa中存放的地址找到指向的空间所以这里的*pa就相当于a printf(%d, *pa);打印出来的*pa就是a的值也可以通过修改*pa的值来修改a的值如下所示可以看出不仅*pa的值变成199a的值也同样修改为199(五)指针变量类型的意义1.指针的解引用下面我们通过两段代码来理解指针变量的意义int a 0x11223344;//整型a存放的是16进制的数字 int* pa a; * pa 0;将整型a的4个字节改成0原来a在内存中存放的值如下修改完之后如下可以看出将4个字节全部修改成0然而当我们创建char类型的变量时int a 0x11223344; char* pa (char*) a; * pa 0;可以看出只能将a的第一个字节改成0所以指针的类型决定了指针解引用时的权限char*类型就只能访问一个字节而int*类型的指针就可以访问4个字节2.指针-整数通过上述的例子我们可以得知指针类型的不同访问的字节也不同我们可以再举一例如下方代码int a 10; int* pa a; char* pc (char*)a; printf(a%p\n, a); printf(pa%p\n, pa); printf(pa1%p\n, pa1); printf(pc%p\n, pc); printf(pc1%p\n, pc1);我们可以看出char类型的指针1之后在原来的基础上地址只变化了一位而int类型的指针1之后则在原来的基础上变化了4位所以可以得知指针的类型决定了指针变化了多少位。那么我们可以再做个练习用指针将数组中的元素依次打印出来如下代码所示int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int sz sizeof(arr) / sizeof(arr[0]); int i 0; int* pa arr[0]; for (i 0; i sz; i) { printf(%d , *(pa i)); }pa表示的是取的是arr数组中第一个元素的地址那我们只需要依次求出arr数组中元素的地址再使用解引用符号*我们就可以依次得出arr数组中的元素3.指针-指针用以下代码举例int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int* pa arr[0]; int* pc arr[9]; printf(%d, pc-pa);指针-指针最终得到的结果就是两个指针(地址)之间的元素个数⚠️:指针-指针必须指向的是同一内存空间像上方的代码中指向的都是arr数组下方代码为错误示范int arr[4] { 1,2,3,4 }; char b e; int* pa arr[2]; char* pc b; printf(%d, pc - pa);我们可以用指针-指针来求字符串长度在之前不用指针如何求字符串长度的呢我们需要用到strlen函数并且strlen函数的返回值是size_t且需要头文件string.h如下所示#include stdio.h #include string.h int main() { char ch[] abcde; size_t len strlen(ch); printf(%d, len); return 0; }那么我们现在知道指针-指针就是两个指针之间的元素个数那么我们可以分别求出字符串长度中第一个元素的地址和’/0’的地址将两个指针(地址)相减就能得到字符串长度了如下代码所示size_t my_strlen(char* p)//指针接受参数 { char* start p[0];//start取ch数组第一个元素的地址 while (*p ! \0) { p; } //p最终变成\0的地址 return p - start; } int main() { char ch[] abcde; size_t len my_strlen(ch);//函数传递的是ch数组其实ch又代表ch数组中第一个元素的地址 printf(%d, len); //所以传递的是地址需要用指针来接受参数 return 0; }4.指针的关系运算两个指针比较大小我们依旧拿我们最熟悉的题目举例打印出数组中的每个元素如下代码所示int main() { int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int sz sizeof(arr) / sizeof(arr[0]); int* pa arr; int* pc arr[sz]; while (pa pc) { printf(%d , *pa); pa; } return 0; }上述代码中pa表示第一个元素的地址而pc表示数组中的第十个元素的后一位的地址不是数组内的所以当papc时解引用打印出元素再通过pa依次打印后面的元素