当前位置: 首页 > news >正文

C语言—指针(针对小白版)

一、基本概念

1、指针是具有指向(指内存单元)含义的数据,指针就是地址(内存单元的编号)

2、C语言处理指针数据:定义指针类型---对应处理的数据,是指针(地址)这种数据

3、定义指针类型变量

基类型 *指针变量名;
//基类型:代表的是一个数据类型(整型、字符型、浮点型、数组类型)
//* :定义指针变量时,*只是修饰作用(代表当前定义的不是普通变量,而是指针类型的变量)
//指针变量名:标识符

基类型含义: 表示[指针变量名]中“地址”指向的“内存空间”上对应的数据类型

4、p是指针类型数据,int * 表示这是指向int型数据的一类指针

int *p=&a;    //p指向了a(这里*只是修饰作用,没有做运算)

5、 a空间的访问:通过a访问——直接访问,通过p访问——间接访问。

6、*p运算过程

  • 拿出p中的地址值,到内存中定位
  • 从定位处开始,向下偏移sizeof(基类型)大小的一块空间
  • 将这块空间当做一个基类型数据或变量来看

7、举例说明

int a=0x12345678;
short *p=&a;
printf("*p=%#x\n",*p);

a 是int型——占4个字节——数据为0x12345678

p 是short*指针类型——p要指向的目标类型是short类型

&a 表示获得一个(int *)类型的地址值

在64位的平台上,所有的指针类型都是64位,8个字节

0x12345678,自小到大:0x78,0x56,0x34,0x12

8、考点:判断电脑大小端

  1 #include<stdio.h>                                                           2 int isLittleEdian(void)3 {4     unsigned int a=1;    //a=1放在低位数据(1 0 0 0)5     unsigned char *p=(unsigned char *)&a;6 7     return *p;    // 8 }

小端返回1,大端返回0;

二、指针的作用

1、被调修改主调

实现:函数传参时必须传的是地址;被调函数中必须有对应的*p(指针的间接访问)的运算

2、函数可以通过指针带出多个结果

#include<stdio.h>
void maxTwo(int x,int y,int *max,int *min)
{if(x>y){*max=x;*min=y;}else{*max=y;*min=x;}
}
int main()
{int a,b,max,min;scanf("%d %d",&a,&b); maxTwo(a,b,&max,&min);printf("max=%d,min=%d\n",max,min);  return 0;
} 

三、指针的运算

1、p+N

表示指向了下一个基类型(相当于跳过了一个基类型)

值的大小是相当于加了一个N*sizeof(基类型)

2、p++

表示指向了下一个基类型(相当于跳过了一个基类型)

值的大小是相当于加了一个1*sizeof(基类型)

3、p-q

p和q必须是同类型的指针

结果表示相差了几个基类型

4、指针不能做(*)(/)(+)

5、指针也可以做关系运算

四、指针操作数组

1、因为数组是一片连续的内存空间,所以指针操作数组只需要知道数组首元素的地址即可

int a[10]={1,2,3,4,5,6,7,8,9,10};&a[10];    //&a[10]取了一个存放int类型数据的空间的地址int * p=&a[10];
int * p=a;

2、数组下标的运算方式,最终还是转换了指针实现

a[i] <=> *(p+i)

3、函数中如果传递数组,只需要传递首元素的地址即可

4、指针打印数组(简便)

void printArray(int *begin int *end)
{while(begin<=end){printf("%d\n",*begin);begin++;}
}printfArray(a,a+len-1);

五、快速排序

思想:分而自治

step1:找到一个基准值        //数组的第一个元素作为基准值

step2:从右边开始,比基准值小的第一个值

  1 #include<stdio.h>2 void printArray(int *a,int len)3 {4     for(int i=0;i<len;i++)                                                                              5     {6         printf("%d\n",*(a+i));7     }8 }9 void swap (int *begin, int *end)10 {11     int temp=*begin;12     *begin=*end;13     *end=temp;14 }15 void quickSort(int *begin,int *end)16 {17     int *p=begin;18     int *q=end;19 20     if (begin>=end)21     {22         return ;23     }24 25     int *k=begin;26     while(begin<end)27     {28         while(begin<end&&*end>=*k)29         {30             --end;31         }32         while(begin<end&&*begin<=*k)33         {34             ++begin;35         }36         swap(begin,end);37     }38     swap(begin,k);39 40     quickSort(p,end-1);41     quickSort(begin+1,q);42 }43 44 int main()45 {46     int a[]={4,3,1,0,2,8,6,7,5,9};47     int len=sizeof(a)/sizeof(a[0]);48     quickSort(a,a+len-1);49     printArray(a,len);50 51     return 0;52 }

 六、指针操作字符串

1、字符串常量,存放在“字符串常量区”,字符串在C语言中,是按照字符数组的方式处理的。

2、说明

同一个字符串常量,在常量区,只会保留一份。

使用的字符串:

  • 一种是存放在栈空间上的字符串  //char s[10]="hello"
  • 一种是存在字符串常量区的字符串   //char*p="hello"(字符串常量区的数据不能被修改)

3、const本身表示只读 ,const修饰的原则,离谁近就是限定谁的。

const放在指针中,可以修饰两个部分

  • 一个是基类型:const char *s和 char const *s

        不能通过*s的方式修改基类型

  • 一个是指针变量:char *const s

        表示s是只读的,s的指向不能被修改

4、strncpy函数

char *strncpy(char *dest,const char *src,size_t)

n<=strlen(src):将前n个字符拷贝过去

n>strlen(src):将src字符拷贝过去后,n如果还没到达0,这时候需要继续拷贝,剩余的次数后续拷贝全是0

5、

七、指针操作二维数组

1、二维数组定义

int(*p)[4]

*表示定义的是一个指针类型变量

p表示是指针变量名,剩余的就是基类型

基类型是一个数组类型int[4]

此时这个指针变量叫做数组指针,因为指向的基类型为数组类型

2、二维数组访问

*(*(p+i)+j)

//*(p+j)   第一维度访问完成,此时整体代表内部的一维数组int[4]这种数组类型的数组名

//*(*(p+i)+j  在第一维的基础上访问第二维度,+j获得了内部一维数组int[4]中具体元素的地址,在此基础上继续做*运算,获得最终的数组元素。

 

八、指针操作函数

1、函数名代表函数的入口地址

2、函数头中 int add(int a,int b)去掉函数名,剩下的就是函数类型

3、书写形式

int (*p)(int a,int b);
//就是一个指向int (int a,int b)这种函数的一个指针变量

4、函数指针:本质是个指针,指向的是一个函数

add()    //定义一个add函数
add(1,2);    //正常调用函数int (*p)(int,int)=add;    //声明一个名为 p 的函数指针p(1,2);    //指针调用函数

函数的指针变量可以用来调用函数

在函数指针中*p中的*运算不起作用

函数指针主要是实现函数回调(callback)

5、qsort函数

#include<stdlib.h> 
void qsort(void *base,   //待排序的数组的首地址 size_t nmemb,   //元素的个数size_t size,   //单个元素的大小 int (*compar)(const void *, const void *) //比较的规则 );
int compare(const void *a,const void *b)
{const int *p=a;const int *q=b;return *p-*q;
}
//*a是空类型指针,如果想通过空类型指针访问具体数据可以这样做:const int *p=a

 compare函数就是回调函数,整个过程就是回调

6、存放函数指针的数组

int(*p[4])(int,int);    //函数指针数组

7、指针函数——本质是个函数,返回值类型为指针类型的函数

 char *strcpy(char *dest, const char *src); //返回值为指针类型的函数 说明:指针函数,意味着返回值是个地址 这个地址,不能是局部变量的地址,可以是字符串常和堆区的地址 

8、malloc函数(指针函数)

  void * malloc(size_t size);功能:申请内存 //堆区 参数:size    --- 表示申请的空间大小 单位字节 返回值:void *  成功 返回申请到的内存空间的首地址 失败 NULL 

使用:

int *p=malloc(sizeof(int)*10);

9、free函数

 void free(void *ptr); //释放 功能:将堆区空间释放 //将之前在用的空间交还给操作系统,告诉操作系统,说这块空间不用了,可以回收参数:ptr   //要求: 代表堆区上的一块空间 //free 用之前 一定有malloc已经申请使用过的 堆区空间

 free(p)释放空间后,一般就要p=NULL

10、void类型指针

 void *  //空类型指针        //万能指针
//void * p ; //指针变量 --- 可以接收任意类型的指针

        注意:
void类型的指针
想要进行指针间接访问的 运算
必须将 void * 类型指针 转换为 具体类型(int,short,float,double)的指针        

11、NULL是空指针

12、考点1:该代码输出“段错误”

考点2:

一个有10个指针的数组,该指针是指向一个整型数的

int *a[10]

一个指向有10个整型数数组的指针

int (*a)[10]

一个指向函数的指针,该函数有一个整型参数并返回一个整型数

int  (*fun)(int)

一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数

int(* a[10])int

13、 一级指针和二级指针

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

九、main函数的参数

int main(int argc,const char *argv[])	

@argc 表示 --- 命令行参数的个数(数组长度)
@argv 表示 --- 存放着命令行字符串的指针数组(数组名)

http://www.dtcms.com/a/339092.html

相关文章:

  • 算法学习day19----博弈论模型--取石子游戏(Python)
  • 懒加载机制实现子模块按需动态导入
  • 全平台轻量浏览器推荐|支持Win/macOS/Linux,极速加载+隐私保护+扩展插件,告别广告与数据追踪!
  • RT-Thread Nano移植到STM32心得(基于GCC、HAL库)
  • Mac下载AOSP源代码
  • UE小:交叉编译linux的坑
  • 【集合框架HashSet底层原理】
  • IDEA:设置彩色输出
  • DataAnalytics之Tool:Metabase的简介、安装和使用方法、案例应用之详细攻略
  • 项目一系列-第5章 前后端快速开发
  • 虚拟环境安装了fastapi但是使用时报错:ModuleNotFoundError: No module named ‘fastapi‘
  • C++利用CerateProcess创建WPF进程并通过命名管道通讯
  • Scikit-learn通关秘籍:从鸢尾花分类到房价预测
  • 项目部署与持续集成
  • Android RxJava数据库操作:响应式改造实践
  • AUTOSAR进阶图解==>AUTOSAR_SWS_FunctionInhibitionManager
  • Spring Ai Chat Memory
  • Python 与 VS Code 结合操作指南
  • 【Vue开发】在Vite+Vue3项目中实现离线Iconify图标方案
  • 【什么是非晶合金?非晶电机有什么优点?】
  • Redis面试题及详细答案100道(71-85) --- 综合篇
  • Vim笔记:缩进
  • KMM跨平台叛逃实录:SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架(代码复用率85%)
  • Qt5 GUI 编程详解
  • 【AI大模型的发展历史】从Transformer到2025年的多模态、推理与开源革命
  • mlir 类型
  • docker 数据卷、自定义镜像操作演示分享(第二期)
  • 【数据结构】堆和二叉树详解(下)
  • SpringAI——向量存储(vector store)
  • SpringClound——网关、服务保护和分布式事务