c基础提高02

申请空间和释放空间必须成对使用

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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值