IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++学习总结2 -> 正文阅读

[C++知识库]C++学习总结2

(1)
实参的a和形参的a的数据类型本质不一样,形参中的数组编译器会把它当成指针处理,
调用函数时需将数组名(内存首地址)和数组的有效长度传给被调用函数。

(2)
数据类型的本质:固定大小内存块的别名
b+1、&b+1 结果不一样:b、&b所代表的数据类型不一样
b代表的数组首元素的地址
&b代表的是整个数组的地址

(3)
一般认为:栈开口向下,不管栈开口向上还是向下,buf的内存地址buf+1永远向上的

(4)
野指针产生的原因:指针变量和它所指向的内存空间变量是两个不同的概念
释放了指针所致的内存空间,但是指针变量本身没有重置成null,造成释放的时候通过if (p1 != NULL)
避免方法:

  • 定义指针的时候,初始化成NULL
  • 释放指针所指向的内存空间后,把指针重置成NULL

(5)
数组 char buf[10] = “abcd”;
指针 char *p = buf;
C语言的字符串是以零结尾的字符串,在C语言中没有字符串类型,通过字符数组来模拟字符串
字符串的内存分配:堆上、栈上、全局区

//strlen() 长度 不包括0
//sizeof() 数据类型内存块的大小

char buf[10] = "abcd";
strlen(buf) 长度不包括\0 =4(字符串)
sizeof(buf) 内存块的大小 =5(字符数组)

char buf1[10] = { 'a', 'b', 'c', 'd' };
char buf2[] = { "abcd" };

cout << strlen(buf1) << endl; //4
cout << strlen(buf2) << endl; //4
cout << sizeof(buf1) << endl; //10
cout << sizeof(buf2) << endl; //5

buf是一个常量指针(只读的常量)
buf++ //error
p++ //ok

(6)
在这里插入图片描述
在这里插入图片描述
一个由C/C++编译的程序占用的内存分为以下几个部分:

  • 栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
    操作方式类似于数据结构中的栈;
  • 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
    收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表;
  • 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的
    全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另 一块区域,程序结束后由系统释放。
  • 文字常量区(只读,不允许修改):常量字符串就是放在这里的。 程序结束后由系统释放 ;
  • 程序代码区 — 存放函数体的二进制代码;

(7)
char *p = “abcd”;
char a[] = “abcd”;

指针p和字符数组都是在栈区,其中"abcd"字面值在常量区,上面的区别是字符数组a会把常量区的"abcd"拷贝到栈中。
那么字符数组a可以修改其中的元素,但指向字符的指针不能修改其指向的字符"abcd"。

//不可通过*p修改字符串的值
char *p = "abcd";
*(p + 2) = '2';

如果真的需要使用"abcd"作为指针,建议写为const char * p=“abcd”;
如果是初始化字符串数组,建议写为char p[]=“abcd”;

//如果p为指针,需要初始化
char *p;
p=malloc(STR_SIZE);
strcpy(p,"abcd");

在这里插入图片描述
(8)

const int a;
int const b; 

const char *c;
char * const d; 
const char * const e;

//第一个第二个意思一样 代表一个常整形数
//第三个 c是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
//第四个 d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
//第五个 e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)

指针变量和它所指向的内存空间变量,是两个不同的概念
看const 是放在 * 的左边还是右边 看const是修饰指针变量,还是修饰所指向的内存空间变量
在这里插入图片描述
在这里插入图片描述
(9)

指针做输入:主调用函数分配内存
指针做输出:被调用函数分配内存

主调函数 被调函数
(1)主调函数可把堆区、栈区、全局数据内存地址传给被调用函数
(2)被调用函数只能返回堆区、全局数据

//堆
char *getMem(int num)
{
	char *p1 = NULL;
	p1 = (char *)malloc(sizeof(char) * num);
	if (p1 == NULL)
	{
		return NULL;
	}
	return p1;
}

//栈
char *getMem2()
{
	char buf[64]; //临时变量 栈区存放
	strcpy(buf, "123456789");
	return buf;
}

void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据

	//tmp = getMem2(); 指向释放的区域
	//return不是把内存块64个字节给return回来,而是把内存块的首地址(内存的标号0xaa11) ,返回给tmp
	tmp = 0xaa11;
	return;
}

(10)
指针数组和数组指针(核心:运算符的优先级)
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”。

1int *p1[10]; //指针数组
[]的优先级比“*”要高。p1先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。
即这是一个数组,其包含10个指向int类型数据的指针,即指针数组。

int* a[4]; //指针数组     
表示:数组a中的元素都为int型指针    
元素表示:*a[i]  *(a[i])是一样的,因为[]优先级高于*

//经常这样使用
typedef int* pInt;
pInt a[4];
2int (*p2)[10];//数组指针
在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int修饰的是数组的内容,即数组的每个元素。
数组在这里并没有名字,是个匿名数组。即p2 是一个指针,它指向一个包含10int 类型数据的数组,即数组指针。
//(*p2)[i]

一维数组 char a[30]				指针 char*
指针数组 char *a[30]			    指针的指针 char **a
二维数组 char a[10][30]			数组指针 char(*a)[30]
3char a[5]={'A','B','C','D'};
char (*p3)[5] = &a;
char (*p4)[5] = a;
 
p3 和p4 都是数组指针,指向的是整个数组。&a 是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。
在C语言里,赋值符号“=”号两边的数据类型必须是相同的,如果不同需要显示或隐式的类型转换。
p3 这个定义的“=”号两边的数据类型完全一致。
而p4 这个定义的“=”号两边的数据类型就不一致了,左边的类型是指向整个数组的指针,右边的数据类型是指向单个字符的指针。

cout << "p3+1 = " << p3 + 1 << endl;//00EFF73D
cout << "&a[1] = " << &a+1 << endl;//00EFF73D

(11)
二级指针三种内存模型示意图
在这里插入图片描述
(12)

指针也是一种变量,占有内存空间,用来保存内存地址
指针是一种数据类型,是指它指向的内存空间的数据类型(指针变量和它指向的内存块是两个不同的概念)
结论:指针的步长,根据所指内存空间类型来定

(13)

两码事:指针变量和它指向的内存块变量
条件反射:指针指向某个变量,就是把某个变量地址赋给指针

*p间接赋值成立条件:3个条件

  • 2个变量(通常一个实参,一个形参)
  • 建立关系,实参取地址赋给形参指针
  • *p形参去间接修改实参的值
int iNum = 0; //实参
int *p = NULL;
p = &iNum;
iNum = 1;
*p =2 ; //通过*形参来间接地改变实参的值

引申: 函数调用时,用n指针(形参)改变n-1指针(实参)的值。
函数调用时,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传出来,此为指针作为函数参数的精髓。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:22:34  更:2021-08-24 15:22:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 5:50:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计