输入
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;