C语言之指针输入和输出特性

输入

void printfStr(const char *s)
{
	printf("%s\n",s);
}
void test()
{
	char *s = malloc(sizeof(char)*100);
	memset(s,0,100);
	strcpy();
	printfStr(s);
}
//打印数组,指向首元素的指针
void printfArray(int *arr,int len);
//数组名做函数参数就会退化为指向数组首元素的指针
int arr[]={1,2,3,4,5};
void printfArray(int *arr, int len)
{

}

void printfStringArr(char **str, int len)
{
	//arr[0]是char* 类型的,arr[0] = *(arr+0);
	for(int i;i<len;i++)
	{
		printf("%s\n",str[0]);
	}
}


void test2()
{
	//char *类型的一个数组,首元素是一个char*指针,用二级指针指向它
	char* str[]={
		"aaa";
		"bbb";
		"ccc"
		"ddd";
	}

}

输出

输出特性,被调函数分配内存,主调函数使用内存,和释放内存

void allocateSpace(char **tmp)
{
	char *p = NULL;
	p = malloc(sizeof(char)*100);
	strcpy(p,"hello world");
	//指针的间接赋值
	*tmp = p;
	
}
void test()
{
	char *p = NULL;
	allocateSpace(&p);
	if(p!=NULL)
	{
		free(p);
		p=NULL;
	}
}

sprintf

int sprintf(char *str, char *format, …);
功能:
根据参数format 字符串来转换并格式化数据,然后将结果输出到str指定的空间中,直到出现字符串结束符‘\0’为止。
返回值:
成功:实际格式化的字符数
失败:-1

//1.格式化字符串
void test1()
{
	char buf[128]={0};
	sprintf(buf,"Hello %s!","Trump");
	printf("Hello %s!\n",buf);
}
//2.拼接字符串
void test2()
{
	char *s1 = "hello";
	char *s2 = "world";
	char buf[128]={0};
	sprintf(buf, "%s %s", s1,s2);
	printf("buf = %s\n",buf);
}
//3.数字字符串
void test2()
{
	int number = 666;
	sprintf(buf, "%d", numer); //把num转成字符串
	printf("buf = %s\n",buf);  
}

void test3()
{
	char **p = malloc(sizeof(char*)*5);
	for(int i=0;i<5;i++)
	{
		p[i] = malloc(64);
		memset(p[i],0,64);
		sprintf(p[i],"Name_%d",i+1);
	}
	for(int i=0;i<5;i++)
	{
		printf("%s\n",p[i]);
	}
	//释放内存
	for(int i-0;i<5;i++)
	{
		if(p[i]!=NULL)
		{
			free(p[i]);
			p[i]=NULL;
		}
	}
	if(p!=NULL)
	{
		free(p);
		p=NULL;
	}
}
//4.设置宽度,右对齐
sprintf(buf,"%8d",num)
//5.设置宽度,左对齐
sprintf(buf,"%-8d",num);

//转成16进制,8进制
void test4()
{
	sprintf(buf,"%o",num);
	sprintf(buf,"%x",num);
}

sscanf

格式作用
%*s或%*d跳过数据
%[width]s读指定宽度的数据
%[a-z]匹配a到z中的任意字符(尽可能多的匹配)
%[aB]匹配a 、B、中的一员,贪婪性
%[^a]匹配非a的任意字符,贪婪性
%[^a-z]表示读取a-z以外的多有字符
/*
#include <stdio.h>
int sscanf(const char *str, const char *format, ...)
功能:从str指定的字符串读取数据,并根据参数format字符串来转换并格式化数据
参数: str:指定的字符串首地址
       format:格式
*/
void test1()
{
	char *str = "12345abcde";
	char buf[32]={0};
	sscanf(str,"%*d%s",buf);
	printf("buf= %s\n",buf); //abcde
}
void test2()
{  
	//忽略中间的空格
	char *str = "abcde 12345"; //注意中间的空格
	char buf[32]={0};
	sscanf(str,"%*s%d",buf);
	printf("buf= %s\n",buf); //12345
}

指针出错点

越界

void test()
{
	char buf[3]= "abc";
	printf("buf:%s\n",buf);
}

改变原指针的指向

 char *p = malloc(64);
 ++p;
 if(p!=NULL)
 {
 	free(p);  //程序奔溃
 	p=NULL;
 }

返回局部变量地址

char *get_srt()
{
	char str[]="abcege";
	...
	return str;
}

同一块内存释放多次

free§完之后,p没有置空(p=NULL)

二级指针

二级指针做形参输出特性

二级指针做参数的输出特性是指由被调函数分配内存

void allocateSpace(char **tmp)
{
	int *arr = malloc(sizeof(int)*10);
	for(int i = 0 ;i<10;i++)
	{
		arr[i]=i+1;
	}
	//指针间接赋值
	*tmp = arr;
}
/*
void freeSpace(void *arr)
{
	if(arr == NULL)
	{
		return ;
	}
	free(arr);
}
*/
void freeSpace(void **arr)
{
	if(*arr == NULL)
	{
		return ;
	}
	if(*arr != NULL)
	{
		free(*arr);
		*arr = NULL;
		arr = NULL;	
	}
	
}

void printfArray(int *arr, int len)
{
	for(int i=0;i<len;i++)
	{
		printf("%d ",arr[i]);
	}
}

void test()
{
	int *pArray = NULL;
	allocateSpace(&pArray);
	printfArray(pArray, 10);
	//freeSpace(pArry);
	//pArry = NULL;	
	freeSpace(&pArray);
}

二级指针做形参输入特性

void printArray(int *arr,int len)
{
	for(int i=0;i<len;i++)
	{
		printf("%d ",*(arr[i]));
	}
	printf("\n");
}

void test()
{
	//堆上分配指针数组
	int **pArray = malloc(sizeof(int *)*3);
	//栈上分配数据空间
	int a1 = 100;
	int a2 = 200;
	int a3 = 300;
	
	pArray[0] = &a1;
	pArray[1] = &a2;
	pArray[2] = &a3;
	
	*(pArray + 0) = &a0;
	*(pArray + 1) = &a1;
	*(pArray + 2) = &a2;
    
    printfArray(pArray, 6);
    free(pArray);
    pArray = NULL;
    
}

一维数组

//可读性,往往要比效率更重要
void printfArray(int *arr, int len)
{
	for(int i=0;i<len;i++)
	{
		printf("%d ",arr[i]);
		printf("%d ", *(arr+i));
	}
}

void test01()
{
	int arr[] = {1,2,3,4};
	//1. sizeof 2.对数组名取地址&arr
	//以上两种情况,数组名不是指向元素的指针, 数组名是数组类型
	//!除了以上两点之外,数组名在其他任何情况下,数组名都是指向首元素的指针
	printf("sizeof arr :%d\n",sizeof(arr)); //sizeof arr: 16
	printf ("arr addr : %d\n", &arr);
	printf("arr+1 addr : %d\n", &arr+1);  //加的是16 ,步长=16
	
	int *p = arr;
	//数组名是一个常量指针
	//arr = NULL//报错
	printfArray(arr, 4);

}

数组指针

如何定义指向数组的指针

先定义数组类型,再定义数组指针类型

void test()
{
	int arr[] ={1,2,3,4,5};
	
	//1.先定义数组类型,再定义数组指针类型
	typedef int (ARRAY_TYPE)[5];  //ARRAY_TYPE 就是包含5个int类型的数组的类型
	ARRAY_TYPE myarray ;// int myarray[5];
	for(int i = 0;i<5;i++)
	{
		printf("%d ",myarray[i]);
	}
	//ARRAY_TYPE *pArray = myarray; //错
	//对数组名取地址代表指向整个数组的指针
	ARRAY_TYPE *pArray = &myarray;
	pArray = &arr;
	//1.*pArray 表示拿到pArray指针指向的整个数组
	//2. *pArray类型就是数组名,数组名即指向首元素类型的指针
	printf(" *(*parray +1 )= %d\n", *(*pArray+1)); // *(*parray +1 )= 2
	
}

在这里插入图片描述

直接定义数组指针类型

typedef int(*ARRAY_POINTER)[5];
ARRAY_POINTER pArr = &arr;

直接定义数组指针变量

一般常用这种

int (*pArrParam)[5] = &arr;

多维数组

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值