C/C++教程

C++基础Day06

本文主要是介绍C++基础Day06,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Day06.2021.11.3

空指针

指针变量指向内存中编号为0的空间

用于初始化指针变量(初始化一个指针,不知道指向哪,就指向空指针)

空指针指向的内存不可以访问

image-20211103083408932

 int* p = NULL;  /*  *p=100是错误的  */

 

野指针

指针变量指向非法的内存空间

比如把一个十六进制的数强转成一个指针变量,但这个指针对应的内存我们没有权利访问,这叫非法,执行会报错:访问权限冲突

image-20211103084953851

 //野指针:应避免出现
     int* p1 = (int*)0x0010;
     cout << *p1 << endl;

 

const修饰指针

  • 修饰指针:常量指针

  • 修饰常量:指针常量

  • 都修饰

image-20211103090407680

  1. 常量指针:指针的指向可以改,但指针指向的值不可以改,图中可以从指向a改成指向b,但是值10不可以改

 //常量指针:指向常量的指针(所以常量不可以变,但可以把指针指向改了)
     int a = 10;
     int b = 20;
     const int* p = &a;
 ​
     //*p = 30;报错
     p = &b;

 

  1. 指针常量:指针的指向不可以改,但指针指向的值可以改,图中不可以从指向a改成指向b,但是值10可以改

 //指针常量:指针本身就是一个常量(所以不能改指向,但可以改指向的值)
     int a = 10;
     int b = 10;
     int* const p = &a;
     //p = &b;报错
     *p = 30;

 

据个人理解方式,const int* p常量指针;int* const p指针常量

也有说法是:const作用于左侧,const int* p由于左侧没东西所以作用在右侧,作用在int上,所以不能改值,int* const p作用在左侧*,作用在指针,所以不能改指向

  1. 既修饰指针又修饰常量

 
  int a = 10;
     const int* const p = &a;

  

指针和数组

利用指针可以访问数组中的每个元素

 
 int arrays[10] = {1,2,3,4,5,6,7,8,9,10};
     cout << "第一个元素:" << arrays[0] << endl;
 ​
     int* p = arrays;//数组名就是数组首地址
 ​
     cout << "第一个元素的地址:" << p << endl;
     cout << "解引用访问数组第一个元素:" << *p << endl;
 ​
     p++;//让指针向后偏移四个字节
 ​
     cout << "解引用访问数组第二个元素:" << *p << endl;

 

利用指针遍历数组

     int* a = arrays;
     for (int i = 0; i < 10; i++) {
         cout << *a << endl;
         a++;
         //或者直接一行下来cout << *(a++) << endl;
     }

 

指针和函数

值传递:形参里放的是实参的数值,形参改变不会影响实参(因为形参是创建新的内存单元,把实参的数据复制过来,操作复制的值,所以不会改变实参中的数据)

地址传递:通过解引用指针来直接操作指针对应的数据,直接操纵实参。

 void swapPtr(int* a, int* b);
 int main() {
 ​
     //地址传递
     int a = 10;
     int b = 20;
 ​
     swapPtr(&a, &b);
 ​
     cout << a << endl;
     cout << b << endl;
 ​
     system("pause");
     return 0;
 }
 ​
 void swapPtr(int* a, int* b) {
     int index = *a;
     *a = *b;
     *b = index;
 }

 

指针、数组、函数

案例:封装一个函数,利用冒泡排序,实现对一个整型数组的升序排列

本来写成这样

 void arraySort(int arrays[]);
 int main() {
     int arrays[] = { 2,5,6,7,9,1,4,8,10,3 };
     arraySort(arrays);
     system("pause");
     return 0;
 }
 void arraySort(int arrays[]) {
     for (int i = 0; i < ( sizeof(arrays) / sizeof(arrays[0])); i++) {
         for (int j = 0; j < ( sizeof(arrays) / sizeof(arrays[0]) - i - 1); j++) {
             if (arrays[j] < arrays[j + 1]) {
                 int index = arrays[j];
                 arrays[j] = arrays[j + 1];
                 arrays[j + 1] = index;
             }
         }
     }
     for (int i = 0; i < ( sizeof(arrays) / sizeof(arrays[0])); i++) {
         cout << arrays[i] << "  " << endl;
     }
 }

 

但是输出结果就只有一个2,找了很久原因,是这样写的:


如果在函数中定义数组A,sizeof(A)是所有数组元素所占用的内存空间字节数,因为编译器在将 C 代码转换成汇编代码时,自动将其替换成了实际的数值,因此可以通过sizeof(A)/sizeof(A[0])计算数组大小。

但是A实际是一个指针,表示的是这个数组首个元素的地址,不信你可以试着尝试cout<<A<<endl,你会发现输出的是一个地址。所以如果此数组在函数外定义,然后作为函数的输入参数传入,则传入的A只能表示指针,所以此时sizeof(A)为A[0]的地址的长度(x86地址长度为32位,即4个字节)。所以sizeof(A)/sizeof(A[0])为1(x86)。所以在我们传入这种数组做参数时,通常同时会再多传一个参数记录数组的长度

没理解的话参考一下

https://blog.csdn.net/qq_40692109/article/details/102766573

https://www.zhihu.com/question/30558041

https://blog.csdn.net/Helianthus_/article/details/54598665

image-20211103205023824


注意:

这里别在排序函数里算数组长度len,通过将数组作为函数参数传递到函数中,以获得数组长度是不可行的。所以,sizoef(arr)的结果是指针变量arr占内存的大小,指针在32位下是4个字节。arr[0]是int类型,sizeof(arr[0])也是4个字节,所以,结果永远是1。这句话同样解释了上面的问题


 
#include"methodState.h"
 void arraySort(int arrays[],int length);
 int main() {
     int arrays[] = { 2,5,6,7,9,1,4,8,10,3 };
     /*这里别在排序函数里算数组长度len,通过将数组作为函数参数传递到函数中,以获得数组长度是不可行的。
     所以,sizoef(arr)的结果是指针变量arr占内存的大小,指针在32位下是4个字节。
     arr[0]是int类型,sizeof(arr[0])也是4个字节,所以,结果永远是1。*/
     int length = sizeof(arrays) / sizeof(arrays[0]);
     arraySort(arrays,length);
     system("pause");
     return 0;
 }
 void arraySort(int arrays[],int length) {
     /*这里实际上可以写void arraySort(int* arrays,int length),因为在函数里数组以指针形式传进来,就可以直接传一个首地址和长度,循环中的arrays[i]都是通过指针访问数组元素*/
     for (int i = 0; i < length; i++) {
         for (int j = 0; j < length - i - 1; j++) {
             if (arrays[j] > arrays[j + 1]) {
                 int index = arrays[j];
                 arrays[j] = arrays[j + 1];
                 arrays[j + 1] = index;
             }
         }
     }
     for (int i = 0; i < length; i++) {
         cout << arrays[i] << " ";
     }
     cout << endl;
 }

 

P63结束

来源:b站黑马

这篇关于C++基础Day06的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!