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++知识库 -> 408_C语言_指针_Day2 -> 正文阅读

[C++知识库]408_C语言_指针_Day2

有关字符串问题

str系列_操作函数

  • strcpy 函数(copy)
  • strlen 函数 (length)
  • strcmp 函数 (compare)
  • strcat 函数 (concatenate)
#include<stdio.h>
#include<string.h>

int main(){
	char a[6]="hello";
	char b[7]=" world";
	char c[6];
	
	printf("strcpy函数:%s\n",strcpy(c,a));
	printf("strlen函数:%d\n",strlen(a));
	printf("strcmp函数:%d\n",strcmp(a,b));
	printf("strcat函数:%s\n",strcat(a,b));
}

在这里插入图片描述

字符串_翻转问题

害,就是想说明一下(就是我把这茬给忘了而已)
别忘了翻转之后,给新的字符串的最后加一个’\0’,因为这个时候和初始化字符串(字符数组)时不太一样,因为不会被自动添加上’\0’,挺有毛病的。

指针有关操作符

  • 与号 &:取地址(引用)
  • 星号 *: 取值(解引用)
  • 所以,&*p == &a == p;
  • 而int* p就表示p是一个整型指针变量;
#include<stdio.h>

int main(){
	int i=5;
	int* p=&i;
	printf("%d\n\n",&*p==&i);
	printf("%d",&*p==p);
}

在这里插入图片描述

指针变量的本质

是一个变量,存的是地址

#include<stdio.h>

int main(){
	int i=5;
	int* p=&i;
	printf("整型变量i的地址:%d\n\n",&i);
	printf("整型指针变量p存储的值:%d\n\n",p);
	printf("*p的值:%d\n\n",*p);
}

在这里插入图片描述

指针的使用场景

值的传递

#include<stdio.h>

void change(int* p)
{
	*p=*p+1;
}

int main(){
	int i=6;
	printf("change之前的i:%d\n\n",i);
	change(&i);
	printf("change之后的i:%d",i);
}

在这里插入图片描述

地址偏移

  • “ * 和 ++ ”两者的优先级相同,需要按从右到左的顺序执行
  • 所以,* p++可看成*(p++),即先执行p++,后执行* p;但因为是后++,所以先执行*p,然后等赋值完成以后,p再++。

也就是说就算是加了括号, * (p++)也是先执行*p,然后等赋值完成以后,p再++。

#include<stdio.h>

int main(){
	int a[3]={1,10,100};
	int b[3]={2,20,200};
	int c[3]={3,30,300};
	
	int* i=a;
	int* j=b;
	int* k=c;
	
	printf("*i 是 %d\n",*i);
	printf("*++i 是 %d\n",*++i);
	printf("*i++ 是 %d\n",*i++);
	printf("*i 是 %d\n",*i);
	printf("此时a[0] 是 %d\n\n",a[0]);
	
	printf("*j 是 %d\n",*j);
	printf("*(++j) 是 %d\n",*(++j));
	printf("*(j++) 是 %d\n",*(j++));
	printf("*j 是 %d\n",*j);
	printf("此时b[0] 是 %d\n\n",b[0]);
	
	printf("*k 是 %d\n",*k);
	printf("++(*k) 是 %d\n",++(*k));
	printf("(*k)++ 是 %d\n",(*k)++);
	printf("*k 是 %d\n",*k);
	printf("此时c[0] 是 %d\n\n",c[0]);
}

在这里插入图片描述
这里面让我难以接受的就是*(p++),我的阅读理解是:先让指针p++,然后再取这个新地址上的值,害,但是发现并不是。

指针与一维数组关系

  • 数组名是一个不变的量,它存了一个值,是该数组的起始地址,所以可以对它进行取值操作。
#include<stdio.h>

int main(){
	int a[4]={1,6,9,10};
	printf("%d\n",sizeof(a));
	printf("%d\n",*(a));
	printf("%d\n",*(a+0));
	printf("%d\n",*(a+1));
	printf("%d\n",*(a+2));
}

在这里插入图片描述

  • 数组名作为实参传递给函数时,其实是弱化为指针的。
#include<stdio.h>

void change(int b[])
{
	b[0]=66;
}

int main(){
	int a[3]={1,10,20};
	change(a);
	printf("a[0]为:%d\n",a[0]);
}

在这里插入图片描述
又可以写做:

#include<stdio.h>

void change(int *b)
{
	b[0]=66;
}

int main(){
	int a[3]={1,10,20};
	change(a);
	printf("a[0]为:%d\n",a[0]);
}

在这里插入图片描述

指针与动态内存申请

  • 需要头文件 #include<stdlib.h> 以及函数 malloc()、函数 free()
  • 其中,malloc() 函数动态申请的空间为堆空间,以字节为单位,不是栈空间(数组)
  • malloc() 函数返回值为void *(无类型指针),然后可以根据存储数据类型的需要,进行强制转换
  • 执行free()释放内存 时必须使用 malloc() 申请时返回的指针值,不能进行任何的偏移,否则会报错
  • 执行完free() 函数之后如果不进行赋值NULL,那么就会生成野指针(指针指向了一个地址是不确定的变量)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(){
	int i;
	char* p;
	scanf("%d",&i);
	p=(char*)malloc(i);
	strcpy(p,"hello world!");
	puts(p);
	free(p);
	p=NULL;
}

在这里插入图片描述

栈空间与堆空间对比

  • 定义数组的时候系统给分配了内存,是栈空间,随函数的完成,系统自动释放
  • 利用 malloc() 函数动态申请的内存,是堆空间,必须用free() 函数,手动释放
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

char* print_stack(char* b)
{
	char p[15];
	strcpy(p,b);
	puts(p);
	return p;
}

char* print_malloc(char* b)
{
	char* q=(char*)malloc(15);
	strcpy(q,b);
	puts(q);
	return q;
}

int main(){
	char a[]="hello world";
	
	char* p;
	p=print_stack(a);	
	puts(p);
	
	printf("\n\n");
	
	char* q;
	q=print_malloc(a);
	puts(q);
}

在这里插入图片描述
WHAT?按理说 main() 函数里的 puts( p) 不应该有输出的呀,栈空间应该是随着函数的执行结束而释放了的哇,怎么会这样,麻了。

经过查阅资料,我发现:

  • 函数执行的时候有自己的临时栈。栈区存储每一个函数在执行的时候都会向操作系统索要资源,栈区就是函数运行时的内存,栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束而释放,由系统自动完成。
  • 但是!!如果p指针指向的内存刚好没有被其他代码破坏时,就可以正常输出出来。

所以说,我这里是刚好没有被破坏,所以才能正常输出。
在这里插入图片描述

字符指针与字符数组

#include<stdio.h>
#include<string.h>

int main(){	
	char q[6]="hello";
	//栈空间可读可写 
	q[0]='H';//正常
	//首地址是常量,不可以修改 
	q="world";//非法
	printf("q[0]是:%c\n",q[0]);
	
	char* p="hello";
	//不可对常量区数据进行修改 
	p[0]='H';//异常
	p="world";//合法 
	printf("p[0]是:%c\n",p[0]);
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 21:52:22  更:2022-03-17 21:55:20 
 
开发: 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年11日历 -2024/11/24 2:56:43-

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