Linux学习--C语言(指针3)

1.指针函数和函数指针

1.1 指针函数

指针函数是函数,函数的返回值是指针

  • 不能返回局部变量的地址
  • 指针函数返回的地址可以作为下一个函数调用的参数

1.2 函数指针

函数指针是指针,指针指向一个函数

cpp 复制代码
#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;
}

int jisuanqi(int x, int y, int (*p)(int x, int y))
{
	return p(x,y);
}

int main(void)
{
	int (*p)(int x, int y) = NULL;
	int num1 = 0;
	int num2 = 0;
	char op = 0;

	scanf("%d %c%d",&num1,&op,&num2);

	switch(op)
	{
		case '+':p = Add;break;
		case '-':p = Sub;break;
		case '*':p = Mul;break;
		case '/':p = Div;break;
	}

	printf("Ret = %d\n",jisuanqi(num1, num2, p));    //p指向某函数

	return 0;
}

2.二级指针

2.1 定义

二级指针是指向一级指针变量的指针

cs 复制代码
int **q;

定义一个指针变量q,占8个字节空间,指向ige指针变量空间,即指向一级指针变量的指针

2.2 使用场景

1.函数体内部想修改函数体外部指针变量的值时,需要传递指针变量的地址即二级指针

2.指针数组传参,数组的数组名是指向数组第一个元素的指针,第一个元素是指针,所以数组名为指向指针的指针即二级指针

3.指针数组和数组指针

3.1 定义

1.指针数组:是数组,数组的每个元素是指针

2.数组指针:是指针,指针指向整个数组

cs 复制代码
int *a[5];
定义一个数组,占40个字节空间,数组名为a,每个元素都是int *型的指针

int (*a)[5];
定义一个指针,占8个字节,指针变量名为a,是指向数组为20个字节空间的指针

3.2 指针数组

cs 复制代码
int *a[5];
char *pstr[5];
  • 存放字符串使用字符型数组,操作字符串使用指针
  • 存放字符串数组使用字符型二维数组,操作字符串数组使用指针数组

3.3 利用指针数组操作二维数组中的字符串实现排序

  • 二维数组存放字符串数组
  • 指针数组元素变化代替二维数组字符串变化,提高程序效率

3.4 数组指针

  • 对一维数组数组名&:值不变 ,类型升级为指向整个数组的指针
  • 对指针数组*:值不变,类型降级为指向数组第一个元素的指针
cs 复制代码
int a[5] = {1,2,3,4,5};


a == &a[0];

a == int *

注意:两种情况a不能理解为int *

  • sizeof:获得数据类型、变量所占字节
  • &:&int * -> int ** &a -> int (*p)[5]

第十一行:&a+1指向下一个数组的首地址,再强制转换为int *型,再减一即减去四个字节,回到数组a的第五个元素,故打印出来为5

3.5 数组指针的使用场景

1.一维数组和指针的关系

  • 数组的数组名是指向数组第一个元素的指针常量
cs 复制代码
int a[5] = {1,2,3,4,5};
int *p = NULL;

p = &a[0];
p = a;

a == &a[0];

a[n] == *(a+n) == *(p+n) == p[n]

2.二维数组和指针的关系

  • 数组的数组名是指向数组第一行的数组指针
cs 复制代码
int a[2][3] = {1,2,3,4,5,6};
int *p = NULL;
int (*q)[3] = NULL;

p = &a[0][0];
p = a[0];
p = *a;
q = a;

a:指向数组第一行元素的数组指针    int (*)[3]
a[0]:指向a[0][0]的指针           int *
a[1]:指向a[1][0]的指针           int *

访问数组第m行第n列元素的方式:
a[m][n]
*(a[m]+n)
*(*(a+m)+n)
*(p+m*N+n)
*(*(q+m)+n)
*(q[m]+n)
q[m][n]

作业

1.封装一个函数,将字符串"12345"转换成整形12345

2.封装函数实现mystrlen,mystrcpy,mystrcat,mystrcmp功能

3.从终端接收五个字符串,对他们排序后输出

cs 复制代码
#include <stdio.h>

int ToNum(char *a)
{
	int i = 0;
	int num[32] = {0};
	int sum = 0;

	while(*a != '\0')
	{

		num[i] = *a - '0';
		sum = sum * 10 + num[i];
		i++;
		a++;
	}

	return sum;
}

int main(void)
{
	char a[32] = "12345";
	
	printf("outnum = %d\n",ToNum(a));

	return 0;
}
cs 复制代码
#include <stdio.h>

int mystrlen(const char *str)
{
	int i = 0;
	while(*str != '\0')
	{
		str++;
		i++;
	}

	return i;
}

char *mystrcpy(const char *pstr, char *pret)
{
	char *ret = pret;

	while(*pstr != '\0')
	{
		*pret = *pstr;
		pret++;
		pstr++;
	}

	return ret;
}

int mystrcmp(const char *pstr, const char *pdst)
{
	while(*pstr == *pdst)
	{
		if(*pstr == '\0')
		{
			return 0;
		}
		pstr++;
		pdst++;
	}

	return *pstr - *pdst;
}

char *mystrcat(char *pstr, const char *pdst)
{
	int len = mystrlen(pstr);
	char *str = pstr;
	pstr += len;

	while(*pdst != '\0')
	{
		*pstr = *pdst;
		pstr++;
		pdst++;
	}
	
	return str;
}

int main(void)
{
	char str[100] = {0};
	char dst[100] = {0};
	char ret[100] = {0};

	gets(str);
	gets(dst);

	printf("strlen:len_str = %d\n",mystrlen(str));

	printf("strcpy:ret_cpy_str = %s\n",mystrcpy(str,ret));

	if(mystrcmp(str,dst) > 0)
	{
		printf("str > cmp\n");
	}
	else if(mystrcmp(str,dst) == 0)
	{
		printf("str = dst\n");
	}
	else
	{
		printf("str < dst\n");
	}
	
	printf("strcat:new_str = %s\n",mystrcat(str,dst));

	return 0;
}
cs 复制代码
#include <stdio.h>
#include <string.h>

int main(void)
{
	char a[5][100] = {0};
	char *pstr[5] = {a[0], a[1], a[2], a[3], a[4]};
	char tmp[100] = {0};
	int i = 0;
	int j = 0;

	for(i = 0; i < 5; i++)
	{
		gets(a[i]);
	}

	for(j = 0; j < 4; j++)
	{
		for(i = 0; i < 4-j; i++)
		{
			if(strcmp(pstr[i], pstr[i+1]) > 0)
			{
				strcpy(tmp,pstr[i]);
				strcpy(pstr[i], pstr[i+1]);
				strcpy(pstr[i+1], tmp);
			}
		}
	}

	for(i = 0; i < 5; i++)
	{
		printf("a[%d] = %s\n",i,a[i]);
	}

	return 0;
}
相关推荐
钟离墨笺11 分钟前
Go 语言-->指针
开发语言·后端·golang
Yu_Lijing15 分钟前
MySQL进阶学习与初阶复习第二天
数据库·c++·学习·mysql
超浪的晨42 分钟前
Java 代理机制详解:从静态代理到动态代理,彻底掌握代理模式的原理与实战
java·开发语言·后端·学习·代理模式·个人开发
l1t1 小时前
开源嵌入式数组引擎TileDB的简单使用
c语言·数据库·c++
咖啡の猫1 小时前
bash的特性-bash中的引号
开发语言·chrome·bash
java叶新东老师1 小时前
idea提交时忽略.class、.iml文件和文件夹或目录的方法
java·开发语言
走过,莫回头1 小时前
在OpenMP中,#pragma omp的使用
开发语言·openmp
red_redemption1 小时前
自由学习记录(74)
学习
Warren981 小时前
Java Collections工具类
java·开发语言·笔记·python·学习·oracle·硬件工程
安庆平.Я1 小时前
STM32——寄存器映射
c语言·stm32·单片机·嵌入式硬件·电脑