笔记①:牛客校招冲刺集训营---C++工程师(指针 -- 函数(分文件编写、引用、函数重载) -- 面向对象(封装、构造、拷贝构造、静态成员(变量/函数)、常函数))

这篇博客详细讲解了C++中的指针、函数和面向对象编程。从指针的基础概念,如地址、野指针、空指针,到指针在数组和字符串中的操作,再到函数的声明、定义、参数传递和返回值。接着,博客深入介绍了函数重载、静态成员、拷贝构造函数和常量指针。最后,讲解了面向对象编程中的封装、构造函数、析构函数和静态成员。内容丰富,适合C++初学者和进阶者学习。
摘要由CSDN通过智能技术生成

0614

C++工程师

第0章 视频课的链接

点这里,这个视频课中只看了第四章和第五章,第五章主要讲的是C++的知识,第四章主要讲的项目相关的知识,本篇笔记是第五章的内容。

第1章 C++岗位知识图谱

第2章 C++八股文

E:\找工作\C++八股文\C面试宝典完整版最最最新.pdf

第3章 算法题视频课

第4章 项目制作与技能提升

笔记链接:Linux高并发服务器开发—笔记1

第5章 高频考点与真题精讲

视频配套资料:E:\读研\C++\牛客网—2021C++秋招集训营

主要内容:
在这里插入图片描述
这里面好像也包括了上面的项目的复习,接下来就把第5章的视频笔记记录下来。

5.1 指针

1.地址所占的内存空间大小

32位系统上占4个字节;64位系统上占8个字节。

int* p = nullptr;
cout << "地址所占内存大小:" << sizeof(p) << endl;

编译运行结果:
地址所占内存大小:8

2.声明和初始化指针变量

在这里插入图片描述

3.野指针和空指针

野指针就是把任意数值赋给指针变量,这没有任何意义,因为野指针指向的区域是未知的。
在这里插入图片描述

4.指针的宽度和跨度(a和&a的区别)

①指针变量的自身类型
②指针变量的指向类型
在这里插入图片描述
③指针变量所取内容的宽度
由指针变量所指向的类型长度决定。

int num = 0x51525354;
int* p = &num;
cout << "*p = " << hex << *p << endl;
short *p1 = (short*)&num;
cout << "*p1 = " << hex << *p1 << endl;

编译运行的结果:
*p = 51525354
*p1 = 5354

指针变量p指向的类型是int类型,int的长度是四个字节
指针变量p1指向的类型是short类型,short的长度是两个字节
在这里插入图片描述

☆☆☆④指针变量+1跨度
由指针变量所指向的类型的大小决定。

示例1:

short* s1 = nullptr;
cout << "s1 = " << s1 << endl;
cout << "s1 + 1 = " << s1 + 1 << endl;

int* p1 = nullptr;
cout << "p1 = " << p1 << endl;
cout << "p1 + 1 = " << p1 + 1 << endl;

编译运行的结果:
s1 = 0
s1 + 1 = 0x2
p1 = 0
p1 + 1 = 0x4

指针变量s1指向的类型是int类型,int的大小是四个字节
指针变量p1指向的类型是short类型,short的大小是两个字节

示例2:

int arr2[10];
cout << "arr2 = " << arr2 << endl;            //arr2 = 0x7fffffffdfe0
cout << "arr2 + 1 = " << arr2 + 1 << endl;    //arr2 + 1 = 0x7fffffffdfe4
cout << "&arr2 = " << &arr2 << endl;          //&arr2 = 0x7fffffffdfe0  dfe0 + 0028(十进制的40) = e008
cout << "&arr2 + 1 = " << &arr2 + 1 << endl;  //&arr2 + 1 = 0x7fffffffe008

arr2是数组首元素的地址,类型是int *或者int arr2[]
arr2 + 1每次加1个int的大小,即4个字节。
&arr2是整个数组的地址,也叫数组指针,类型是int (*)[10]
&arr2 + 1每次加整个数组的大小,即40个字节。
(注:arr2&arr2都是地址,前者指向一个数组元素的地址,后者指向整个数组的地址,所以它们的跨度不一样;
其中&arr2可以看下面的7.数组指针和指针数组

示例3:(这个示例好)

#include<stdlib.h>
#include<stdio.h>
int main(int argc, char* argv[]){
   

    int a[4] = {
   1, 2, 3, 4};
    //int* p = (int*)(&a + 1); //结果是4
    int* p = (int*)(a + 1); //结果是1
    printf("%d\n", *(p - 1));
    
    return 0;
}

5.const和指针 —(指针常量和常量指针)

指针常量和常量指针,见C++笔记4:C++中const和指针

指针常量(常指针):指针是个常量,指向固定;int* const p;
常量指针:指向常量的指针,指向的值固定;const int* p;

示例:

#include<iostream>
using namespace std;

int main(){
   
    int num1 = 10;
    int num2 = 20;
    int num3 = 30;
//常量指针:指向常量的指针
    int const *p1;
    p1 = &num1;//指针p1(我)指向num1(你) ---指向的值固定,即(*p1)不能改变,但p1可以改变
    //(*p1)++;//不能通过p1来修改num1的值(不能通过我来修改你)
    cout << "p1 = " << p1 << "; &num1 = " << &num1 << "; num1 = " << num1 << endl;//p1 = 0x7fffffffe038; &num1 = 0x7fffffffe038; num1 = 10
    ++num1; //可以通过num1来修改自己的值(可以通过你来修改你自己)
    cout << "p1 = " << p1 << "; &num1 = " << &num1 << "; num1 = " << num1 << endl;//p1 = 0x7fffffffe038; &num1 = 0x7fffffffe038; num1 = 11
    p1 = &num2;//可以修改p1指向的内容(可以修改我自己指向的内容)
    cout << "p1 = " << p1 << "; &num1 = " << &num1 << "; num1 = " << num1 << endl;//p1 = 0x7fffffffe03c; &num1 = 0x7fffffffe038; num1 = 11(p1改变)

//指针常量:指针是个常量,所以必须要初始化 ---指向固定,即p2不能改变,但(*p2)可以改变
    //int * const p2;//没初始化为报错
    int * const p2 = &num2;//指针p2(我)指向num2*(你)
    cout << "p2 = " << p2 << "; &num2 = " << &num2 << "; num2 = " << num2 << endl;//p2 = 0x7fffffffe03c; &num2 = 0x7fffffffe03c; num2 = 20
    (*p2)++;//可以通过p2来修改num2的值(可以通过我来修改你的值)
    cout << "p2 = " << p2 << "; &num2 = " << &num2 << "; num2 = " << num2 << endl;//p2 = 0x7fffffffe03c; &num2 = 0x7fffffffe03c; num2 = 21((*p2)改变)
    ++num2; //也可以通过num2来修改自己的值(可以通过你来修改你自己)
    cout << "p2 = " << p2 << "; &num2 = " << &num2 << "; num2 = " << num2 << endl;//p2 = 0x7fffffffe03c; &num2 = 0x7fffffffe03c; num2 = 22
    //p2 = &num3;//不能修改p2指向的内容(不可以修改我自己指向的内容)
    
//静态常量指针和普通的常量指针
    static const char*p3;
    char const *p4;
    cout << "p3 = " << p3 << endl;//ok,因为静态变量会默认赋初值
    //cout << "p4 = " << p4 << endl;//编译不过,因为p4的初始值不确定
    
    return 0;
}

题目:(静态变量和普通变量 & 常量指针)
在这里插入图片描述

6.指针在数组中的操作(☆☆☆ * 和 前缀++ 和 后缀++ )

参考链接:*与++优先级

  • 前缀递增递减*优先级相同,从右到左;
  • 后缀递增递减比前缀优先级高,从左到右。

*后缀++
*p++ 相当于*(p++) :先输出*p,然后p自加一;
(*p)++ :输出*p,然后(*p)自加一;

*前缀++
*++p 相当于*(++p):先让p自加一,然后再取*p
*(++p):先让p自加一,然后再取*p
++*p 相当于 ++(*p):先输出*p,然后(*p)自加一;
++(*p):先输出*p,然后(*p)自加一;

示例1:

#include<iostream>
using namespace std;

int main(){
   
    // 案例:
    //前缀递增递减和*优先级相同,从右到左;
    //后缀递增递减比前缀优先级高,从左到右;
    int arr1[5] = {
    10,20,30,40,50 };
    int* p2 = arr1;

    cout << *p2++ << endl;      //10 p2指向arr1[1]
    cout << (*p2)++ << endl;    //20 p2指向arr1[1], arr[1]变成21
    cout << *p2 << endl;        //21
    cout << *++p2 << endl;      //30 p2指向arr1[2]
    cout << *(++p2) << endl;    //40 p2指向arr1[3]
    cout << ++*p2 << endl;      //40 p2指向arr1[3],arr1[3]变成41
    cout << *p2 << endl;        //41
    cout << ++(*p2) << endl;    //41 p2指向arr1[3],arr1[3]变成42
    cout << *p2 << endl;        //42
    
    for(int& x : arr1) cout << x << "; ";//10; 21; 30; 42; 50; 
    cout << endl;

    return 0;
}

示例2:
int* p = arr;
p[i]等价于*(p + i),等价于*(arr + i) ,等价于arr[i]

int* p1 = &arr[2];
p1[1]等价于*(p1 + 1),即arr[3]
p1[-1]等价于*(p1 - 1),即arr[1]

    // 创建一个数组
    int arr[5] = {
    10,20,30,40,50 };
    int* p = arr; //等价于 int* p; p = arr;
    //int (*p)[5] = &arr;//数组指针
    //int *p[5];//指针数组
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
   
        cout << p[i] << endl;//p[i]等价于*(p + i),等价于*(arr + i) ,等价于arr[i]
    }
    cout << sizeof(arr) << endl; // 20=4*5
    cout << sizeof(p) << endl; // 8个字节,64位系统
    // 不要认为p只能保存首元素的地址
    int* p1 = &arr[2];
    cout << "p1[1] = " << p1[1] << endl;//p1[1]等价于*(p1 + 1),即arr[3]
    cout << "p1[-1] = " << p1[-1] << endl;//p1[-1]等价于*(p1 - 1),即arr[1]

7.数组指针和指针数组

数组指针:指向数组的指针

int arr[5] = {
    10,20,30,40,50 };
int (*p)[5] = &arr;//数组指针

指针数组:元素为指针(地址)的数组

int num1 = 10;
int num2 = 20;
int num3 = 30;
int num4 = 40;
int * arr[4] = {
   &num1, &num2, &num3, &num4};

在这里插入图片描述
示例1:(数组指针)

int arr[10];

int (*p)[5] = &arr;//错误,"int (*)[10]" 类型的值不能用于初始化 "int (*)[5]" 类型的实体
int (*p)[10] = &arr;//ok
int (*p)[10] = arr;//错误,"int *" 类型的值不能用于初始化 "int (*)[10]" 类型的实体

cout << arr << endl;//arr的类型:int * 或者 int arr[]
cout << &arr << endl;//&arr的类型为:int (*)[10]

arr的类型:int * 或者 int arr[]
&arr的类型为:int (*)[10],也叫数组指针
注:arr&arr都是地址,前者指向一个数组元素的地址,后者指向整个数组的地址,所以它们的跨度不一样;

示例2:(指针数组)

char name1[10];
char name2[10];
char name3[10];

char *pp[3] = {
   name1, name2, name3};//ok
char *pp[3] = {
   &name1, &name2, &name3};//错误,
							//"char (*)[10]" 类型的值不能用于初始化 "char *" 类型的实体

name1的类型:char * 或者 char name1[10]
&name1的类型为:char (*)[10],也叫数组指针
而指针数组中存放的是指针变量,即int *或者char *,所以上面示例中的最后一行是错误的。

示例3:(数组指针)

	char aaa[][3] = {
   'a', 'b', 'c', 'd', 'e', 'f'};
	char (*p)[3] = aaa;
	cout << "" << **p << endl;//'a'
	cout << "" << *(*(p + 1) + 2) << endl;//'f'
	p++;
	cout << "" << **p << endl;//'d'

8.二级指针(加引用和解引用的规则)

int num = 10;
int * p = &num;
int ** q = &p;

*p : 获取的是 num 的值
*q : 获取的是 num 的地址值
**q : 获取的是 num 的值

加引用的规则:
numint类型,给num前面加一个&,就要给int后面加个*,那么&num就是int*类型;
pint*类型,给p前面加一个&,就要给int*后面加个*,那么&p就是int**类型。

解引用的规则:
qint**类型,给q前面加一个*int**就要减个*,那么*q就是int*类型;
pint*类型,给p前面加一个*int*就要减个*,那么*p就是int类型。

9.☆☆☆字符数组 char指针 字符串常量

这部分内容之前在
C++ Primer Plus(嵌入式公开课)—第4章 复合类型中的第四章4.2 字符串(C语言)

我的C++八股文中的笔记5
中有提到,这里做一个完整的总结。

示例1:arr是数组首元素的地址

int arr[3] = {
    1,2,3 };
int* p = arr;
cout << p << endl; // 0x7fffffffdffc 输出的是地址值。
cout << *p << endl;//1 输出的是元素值

示例2:flower 也是字符数组的首元素地址

#include <iostream>
#include<string.h> // strlen函数的头文件
using namespace std;
int num = 20;//全局变量
int main() {
   

    //1.字符数组(C风格的字符串)
	char flower[10] = "rose";//等价于 char flower[10] = {'r', 'o', 's', 'e', '\0'};
	cout << flower << endl;//rose
    cout << "sizeof(flower) = " << sizeof(flower) << endl;//10 字符数组的大小
    cout << "strlen(flower) = " << strlen(flower) << endl;//4 字符串的大小
    cout << "字符数组的地址:" << &a
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值