【C语言】深入理解指针

什么是指针?

指针就是地址,int a;a是整形变量,而int* p=&a; (给指针p赋值是给p一个地址) 带*就代表是一个指针是int类型指针是存放int类型数据的指针,指针能够通过地址解引用获取到变量值,也能通过指针修改对应地址的值。指针更多的功能往下看我会一一讲解。

*号用于定义指针和解引用操作,当int a=10; int *p =&a,
就能通过*号通过地址找到存放的值如printf("%d",*p);屏幕会显示a变量中存放的值

字符指针

char a='A';
char *p=&a;//字符类型数据存放到字符指针,整形数据类型存放到整形指针中
printf("%c",*p); //屏幕会显示'A'
const char* ptr1="hello world" //ptr1会存放第一个字符'h'的地址,内容不能更改
const char* ptr2="hello world"//编译器不会再从新找一块空间存放"hello world",因为上一条指令已经给它开辟了空间,"hello world"是字符串常量,所以不会在开辟空间。
int main()
{
	char arr1[]="hello world";
	char arr2[]="hello world";
	const char *arr3="hello world";
	const char *arr4="hello world";
	if(arr1==arr2)//地址比较
	{
	  	printf("YES");
	}else
	{
		printf("NO");
	}
	
	if(arr3==arr4)
	{
		printf("YES");
	}else
	{
		printf("NO");
	}
	
}

输出结果为NO YES
字符串"hello world"定义在数组中是变量,所以即使两个数组中值一样也会在不同的地址空间存放相同值。
在指针初始化中是常量,常量无需在开辟空间(第一个常量"helloworld"已经在内存中开辟了空间,执行到第二个常量"hello world"时,编译器就不会在开辟一摸一样的常量,浪费空间 ,所以两个指针指向的地址是一样的),所以第一条结果为NO,第二条结果为YES。

void指针类型能够接收任何数据类型,类似于垃圾桶,但不能解引用使用。

在这里插入图片描述

二级指针

二级指针的作用?

二级指针是存放一级指针的地址

	int a = 10;
	int* pa = &a;
	int **pb = &pa;
	printf("%d\n",a);//输出10
	printf("%d\n",*pa);//输出a的值
	printf("%d\n",**pb);//间接输出a的值(*pb得到的是pa指向的地址,**pb找到的是pa指向地址的值)

在这里插入图片描述

在这里插入图片描述

指针数组

指针数组是指针还是数组?
答:是数组,是存放指针(地址)的数组
在这里插入图片描述
运行结果为10 20 30 40

数组指针

数组指针是指向数组的指针

在这里插入图片描述


#include <stdio.h>
//下列哪项接受参数是正确的?
void fun(int arr[])//YES 数组传参用数组接收没问题,其本质上在这里并不是数组而是指针
{
    ;
}

void fun(int arr[10])    //YES
{}

void fun(int *arr)      //YES   实参是地址,用指针接收没问题

{
    ;
}

void fun(int **arr)     //NO    二级指针 接收一级指针
{
    ;
}

void test(int* arr2[10])    //YES
{
    ;
}

void test (int* p)          //YES   数组名是首元素地址,数据类型是int* 用一级指针接收
{
    ;
}
int main() {
    int arr1[10];
    fun(arr1);
    int* arr2[10];
    test(arr2);
    return 0;
}

二维数组数组名传参,不能使用一级或者二级指针接收,因为二维数组首元素的地址是行地址,要使用数组指针接收。

函数指针

函数指针是指向函数的指针

#include<stdio.h>
int Add(int x,int y)
{
    return x+y;
}
int main()
{
    //int *p(int, int)=Add; 写法错误,p会先和()结合,便不是指针。
    int(*p)(int ,int)=Add;//Add==&Add
    int k=(****p)(3,4);//p(3,4)==(*p)(3,4)==(n个* p)(3,4)
    printf("%d\n",k);
    return 0;
}

函数指针数组

存放函数指针的数组,格式:int(*p[4])(int ,int)
解释:数组有四个元素每个元素指向一个函数,每个函数参数是int int,返回值为int
制作一个简易计算器

#include<stdio.h>
int Add(int x,int y)
{
    return x+y;
}
int Sub(int x,int y)
{
    return x-y;
}
int Mul(int x,int y)
{
    return x*y;
}
int Div(int x,int y)
{
    return x/y;
}
void menu()
{
    printf("*************************\n");
    printf("*********1.Add***********\n");
    printf("*********2.Sub***********\n");
    printf("*********3.Mul***********\n");
    printf("*********4.Div***********\n");
    printf("*********0.退出游戏********\n");
    printf("*************************\n");
}
int main()
{
    int(*p[4])(int ,int)={0,Add,Sub,Mul,Div};
    int input;
    menu();
    int x,y;
    scanf("%d",&input);
    do
    {
    	scanf("%d",&input);
        if(input>=1&&input<=4)
        {
            scanf("%d %d",&x,&y);
            printf("%d",(p[input](x,y)));
        }else if(input==0)
        {
            printf("退出游戏");
        }else{
            printf("输入有误");
        }
    }while(input);
    return 0;
}

指向函数指针数组的指针

void(*(*ptr)[5])(int ,int)=&ptrr;
指针指向数组,数组5个元素每个元素都是函数指针

qsort的使用

头文件#include<stdlib.h>

#include<stdio.h>
#include<stdlib.h>
int cmp(const void* e1,const void* e2){
    return (*(int*)e1-*(int*)e2);
}
int main()
{
    int arr[10]={1,3,5,7,9,2,4,6,8,10};
    qsort(arr,sizeof(arr)/sizeof(arr[0]),sizeof(arr[0]),cmp);
    //  要排序的数组。 数组长度。              元素大小       比较函数
    for(int i=0;i<10;i++)
    {
        printf("%d\n",arr[i]);
    }
    return 0;
}

利用冒泡排序模拟实现qsort

#include<stdio.h>
#include<stdlib.h>
int cmp(const void* e1,const void* e2){
    return (*(int*)e1-*(int*)e2);
}
void swap(void*arr1,void*arr2,int k)
{
    int i=0;
    for(i=0;i<k;i++)
    {
        char m=*((char*)arr1+i);
        *((char*)arr1+i)=*((char*)arr2+i);
        *((char*)arr2+i)=m;
    }
}
void fun(void*arr,int sz,int k,int(*p)( void*, void*))
{
    int i=0,j;
    for(i=0;i<sz;i++)
    {
        for(j=0;j<sz-i-1;j++)
        {
            if(p((char*)arr+j*k,(char *)arr+(j+1)*k)>0)
            {
                swap((char*)arr+j*k,(char *)arr+(j+1)*k,k);
            }
        }
    }
}
int main()
{
    int arr[10]={1,3,5,7,9,2,4,6,8,10};
  //  qsort(arr,sizeof(arr)/sizeof(arr[0]),sizeof(arr[0]),cmp);
    //  要排序的数组。 数组长度。              元素大小       比较函数
    fun(arr,sizeof(arr)/sizeof(arr[0]),sizeof(arr[0]),cmp);
    for(int i=0;i<10;i++)
    {
        printf("%d\n",arr[i]);
    }
    return 0;
}

在这里插入图片描述

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值