申请空间和释放空间必须成对使用
day01总结:
指针类型的定义与使用
指针类型大小:
在32位操作系统下所有指针类型都是4个字节大小;
在64位操作系统下所有指针类型都是8个字节大小;
空指针,野指针,万能指针
空指针
1、操作空指针对应的空间会造成程序异常终止
2、释放空指针不会报错,多次释放空指针也不会报错
野指针
1、指针变量指向野指针不会程序异常终止
2、操作野指针对应的空间或者释放野指针对应的空间会造成程序异常
万能指针
使用万能指针前需要强制转换成对应变量指针类型(确定步长)
产生野指针的几种情况
1、指针变量未初始化
2、指针释放后未置为空
3、指针操作超过作用域
指针间接访问和步长:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = NUll;
p = arr;
/*/------p = arr = arr[0]----------/*/
*(++p) = 10;//2 -> 10
p[3] = 10;//5 -> 10
*(p-2) = 10;//数组越界
p = 10;// 野指针
p = arr[5];//野指针
*p = 10;//操作野指针
数组名作为函数参数传递退化为指针
指针数组:数组的每个元素都是指针类型 ----->int* p[3](数组的每个元素都是指针)
数组指针:指向数组首地址的指针---------->int (*P)[3] (指向数组的首地址)
二维数组使用指针转置
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define LEN 5
int main( ) {
int arr[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9},
};
//int **p = arr;
int (*p)[3] = arr;
for(int i = 0; i < 3;i++)
{
for(int j = 0; j < i;j++)
{
int tmp = *(*(p + i) + j);
*(*(p + i) + j) = *(*(p + j) + i);
*(*(p + j) + i) = tmp;
}
}
for(int i = 0; i < 3;i++)
{
for(int j = 0; j < 3;j++)
{
printf("%d",arr[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
指针作为函数参数传递
同级传递属于值传递
不同级别间传递属于地址传递
用1级指针形参,去间接修改了0级指针(实参)的值。
用2级指针形参,去间接修改了1级指针(实参)的值。
用3级指针形参,去间接修改了2级指针(实参)的值。
用n级指针形参,去间接修改了n-1级指针(实参)的值。
字符串操作:
字符串和字符数组区别:是否有字符串结束标志'\0'
1、MyStrlen
int MyStrlen1(char* str)
{
if(!str)
return;
int len = 0;
while(*strl++)
{
len++;
}
return len;
}
int MyStrlen2(char* str)
{
if(!str)
return;
char* tmp = str;
while(*tmp)
tmp++;
return tmp - str;//步长
}
2、MyStrcat
//数组
void MyStrcat1(char* dest,char* src)
{
if(!dest || !src)
return;
int len = 0;
while(dest[len] != '\0')
{
len++;
}
int i = 0;
while(src[i] != '\0')
{
dest[i + len] = src[i];
i++;
}
dest[i+len] = '\0';
}
//指针
int MyStrcat2(char* dest,char* src)
{
if(!dest || !src)
return;
char* tmp = dest;
while(*tmp)//找到dest为'\0'的地址
tmp++;
while(*tmp++ = *src++);//赋值
}
3、MyStrcpy
//数组
void MyStrcpy1(char* dest,char* src)
{
if(!dest || !src)
return;
int i = 0;
while(src[i] != '\0')
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
}
//指针
void MyStrcpy2(char* dest,char* src)
{
if(!dest || !src)
return;
while(*dest++ = *src++);
}
4、字符串反转
//数组
void reverse_string1(char* str)
{
int len = 0;
while(str[len] != '\0')
{
len++;
}
len -= 1;
int i = 0;
while(i < len)
{
int tmp = str[i];
str[i] = str[len];
str[len] = tmp;
i++;
len--;
}
}
//指针
void reverse_string2(char* str)
{
char* start = str;
char* end = arr + strlen(str) - 1;
while(start < end)
{
int tmp = *start;
*start = *end;
*end = tmp;
start++;
end--;
}
}
字符串的格式化读写:
格式
|
作用
|
%*s或%*d
|
跳过数据
|
%[width]s
|
读指定宽度的数据
|
%[a-z]
|
匹配a到z中任意字符(尽可能多的匹配)
|
%[aBc]
|
匹配a、B、c中一员,贪婪性
|
%[^a]
|
匹配非a的任意字符,贪婪性
|
%[^a-z]
|
表示读取除a-z以外的所有字符
|
void R_1()
{
char arr[] = "1+2=3";
int a,b,c;
char d,e;
sscanf(arr,"%d%c%d%c%d",&a,&d,&b,&e,&c);
printf("%d%c%d%c%d",a,d,b,e,c);
}//打印:1+2=3
//固定位数读取
void R_2()
{
char arr[] = "111+222=333";
int a;
sscanf(arr,"123+%3d",&a);
printf("%d",a);
}//打印:222
void R_3()
{
char arr[] = "111+222=333";
int a;
char ch[10];
sscanf(arr,"%4c%3d",ch,&a);
printf("%d",a);
}//打印:222
//1. 跳过数据
void test01(){
char buf[1024] = { 0 };
//跳过前面的数字
//匹配第一个字符是否是数字,如果是,则跳过
//如果不是则停止匹配
sscanf("123456aaaa", "%*d%s", buf);
printf("buf:%s\n",buf);
}
//2. 读取指定宽度数据
void test02(){
char buf[1024] = { 0 };
//跳过前面的数字
sscanf("123456aaaa", "%7s", buf);
printf("buf:%s\n", buf);
}
//3. 匹配a-z中任意字符
void test03(){
char buf[1024] = { 0 };
//跳过前面的数字
//先匹配第一个字符,判断字符是否是a-z中的字符,如果是匹配
//如果不是停止匹配
sscanf("abcdefg123456", "%[a-z]", buf);
printf("buf:%s\n", buf);
}
//4. 匹配aBc中的任何一个
void test04(){
char buf[1024] = { 0 };
//跳过前面的数字
//先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停止匹配
sscanf("abcdefg123456", "%[aBc]", buf);
printf("buf:%s\n", buf);
}
//5. 匹配非a的任意字符
void test05(){
char buf[1024] = { 0 };
//跳过前面的数字
//先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停止匹配
sscanf("bcdefag123456", "%[^a]", buf);
printf("buf:%s\n", buf);
}
//6. 匹配非a-z中的任意字符
void test06(){
char buf[1024] = { 0 };
//跳过前面的数字
//先匹配第一个字符是否是aBc中的一个,如果是,则匹配,如果不是则停止匹配
sscanf("123456ABCDbcdefag", "%[^a-z]", buf);
printf("buf:%s\n", buf);
void W_test(){
//格式化字符串
char buf[1024] = { 0 };
sprintf(buf, "你好,%s,欢迎加入我们!", "John");
printf("buf:%s\n",buf);
memset(buf, 0, 1024);
sprintf(buf, "我今年%d岁了!", 20);
printf("buf:%s\n", buf);
//拼接字符串
memset(buf, 0, 1024);
char str1[] = "hello";
char str2[] = "world";
int len = sprintf(buf,"%s %s",str1,str2);
printf("buf:%s len:%d\n", buf,len);
//数字转字符串
memset(buf, 0, 1024);
int num = 100;
sprintf(buf, "%d", num);
printf("buf:%s\n", buf);
//设置宽度 右对齐
memset(buf, 0, 1024);
sprintf(buf, "%8d", num);
printf("buf:%s\n", buf);
//设置宽度 左对齐
memset(buf, 0, 1024);
sprintf(buf, "%-8d", num);
printf("buf:%s\n", buf);
//转成16进制字符串 小写
memset(buf, 0, 1024);
sprintf(buf, "0x%x", num);
printf("buf:%s\n", buf);
//转成8进制字符串
memset(buf, 0, 1024);
sprintf(buf, "0%o", num);
printf("buf:%s\n", buf);
}