7/12作业

三、指针指向数组

3.1 指针与数组的关系

1> 一维数组的数组名,本质上是一个该数组的第一个元素的地址

int arr[5]; arr &arr[0]

2> 数组名是一个地址常量,不能被重新赋值,但是,数组名可以进行偏移

3> 二维数组的数组名,从数值上来说也是一个该数组第一个元素的地址

int arr[3][4]; arr &arr[0] arr[0] &arr[0][0] arr[1] &arr[1][0]

3.2指针与一维数组的关系实现

1:指针与一维数组的关系

#include<stdio.h>

int main(int argc, char const *argv[])
{
    int arr[]={1,2,3,4,5};
    int len = sizeof(arr)/sizeof(arr[0]);

    int *ptr =arr;

    
    //从值的角度
    printf("数据元素分别是:\n");
    for (int i = 0; i < len; i++)
    {
        printf("%d\t",*(arr+i));//arr是指针常量不能自增
    }
    printf("\n");

    //从数组名的角度
    for (int i = 0; i < len; i++)
    {
        printf("%d\t",arr[i]);
    }
    printf("\n");  

    //从指针变量的角度
        for (int i = 0; i < len; i++)
    {
        printf("%d\t",*(ptr+i));
    }
    printf("\n");

    //从指针的角度
        for (int i = 0; i < len; i++)
    {
        printf("%d\t",ptr[i]);
    }
    printf("\n");

        for (int i = 0; i < len; i++)
    {
        printf("%d\t",*(ptr++));//ptr是指针变量,可以自增
    }
    printf("\n");

    return 0;
}

2: 指针指向一维整型数组作为函数参数传递

当实参使用的是数组名进行传递时,本质上传递的是数组首元素的地址

被调函数的形参可以是一个数组接收,也可以是一个指针变量接收

虽然使用的是数组接收,但是,本质上也还是使用的是指针接收

#include<myhead.h>

//使用数组接受
/*
void sort(int arr[], int n)
{
    for(int i=1; i<n; i++)
    {
        for(int j=0; j<n-i; j++)
        {
            if(arr[j] > arr[j+1])
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    printf("排序成功\n");
}
*/

//使用指针接受
void sort(int *arr, int n)
{
    for(int i=1; i<n; i++)
    {
        for(int j=0; j<n-i; j++)
        {
            if(arr[j] > arr[j+1])   //if(*(arr+j) > *(arr+j+1))
            {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    printf("排序成功\n");
}









/***************************主程序**********************/
int main(int argc, const char *argv[])
{
    int arr[5] = {3,9,2,7,6};

    //调用排序函数,将数组进行排序
    sort(arr, 5);     //sort(&arr[0], 5)

    printf("排序后的结果为:");
    for(int i=0; i<5; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");

    return 0;
}

练习:

主函数中定义一个长度为8的数组,调用自定义函数完成输入、自定义函数完成输出、自定义函数求最大值、自定义函数完成数组的逆置。并对这些函数进行测试。要求,形参使用指针接收

#include<stdio.h>
//(排序)使用指针来接受
void sort(int *arr,int n)
{
    for (int i = 1; i < n; i++)
    {
        for (int j = 0; i < n-i; j++)
        {
            if (arr[j]>arr[j+1])
            {
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
            
        }
        
    }
    
}
//求数组最大值
int max(int *arr,int *size)
{
    int max=0;
    for (int i = 0; i < *size; i++)
    {
        if (arr[i]>max)
        {
            max=arr[i];
        }
        
    }
    return max;
}
//输入数组
void input_arr(int *arr,int *size)
{
    printf("请输入实际个数数");
    scanf("%d",size);
    for (int i = 0; i < *size; i++)
    {
        printf("请输入第%d个数:",i+1);
        scanf("%d",arr+i);
        getchar();

    }
    
}

//输出数组
void print_arr(const int *arr,int *size)
{
    for (int i = 0; i < *size; i++)
    {
        printf("%d\t",arr[i]);
    }
    printf("\n");
}

//倒置
void daozhi(const int *arr,int *size)
{
    int brr[8]={0};
    for (int i = 0; i < *size; i++)
    {
        brr[i]=arr[*size-1-i];
    }
    for (int i = 0; i < *size; i++)
    {
        printf("%d\t",brr[i]);
    }
    printf("\n");
    
}

int main(int argc, char const *argv[])//*argv[]是指针数组
{
    int arr[8]={0};
    int size=0;  //数组实际大小
    input_arr(arr,&size);
    printf("最大值为%d\n",max(arr,&size));
    daozhi(arr,&size);
    print_arr(arr,&size);
    return 0;
}

3: 指针指向一维字符数组作为函数参数传递

1、由于字符串有结束标识,所以接收字符串时,可以不用接收字符串长度

2、一般对传入的字符串如果不进行更改操作的话,需要加上关键字const修饰

#include<myhead.h>
#include<ctype.h>

//定义筛选函数
void fun(const char *src, char *dest)
{
    char temp = 0;

    //遍历所有src中的字符
    while(temp = *src++)
    {
        //判断该字符是否为字母字符
        if(isalpha(temp))
        {
            *dest++ = temp;
        }
    }
    *dest = '\0';          //给新串放入结束标志
}


/***************主程序*********************/
int main(int argc, const char *argv[])
{
    //功能:传入一个源字符串,调用函数实现,将该字符串中的
    //字母字符放入新数组中传递给主调函数
    char src[100] = "";
    char dest[100] = "aaaaaaaaaaaaaaa";

    printf("请输入一个字符串:");
    gets(src);

    //调用挑选数据的函数
    fun(src, dest);

    printf("新字符串为:%s\n", dest);


    return 0;
}

3、指针与字符串的关系

1、字符串本质上是一个指针常量,可以定义一个指针指向一个字符串
2、当一个指针指向一个字符串时,不能通过该指针改变字符串中的内容

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //定义数组存储字符串、
    char str[100] = "hello world";

    //定义指针指向字符串常量
    char *ptr = "I love China";

    printf("str = %s, ptr = %s\n", str, ptr);

    str[0] = 'H';         //给数组元素进行重新赋值
    //ptr[0] = 'i';        //?

    printf("str = %s, ptr = %s\n", str, ptr);

    //请看案例
    char s[100] = "acb\x12ef";
    printf("strlen(s) = %ld\n", strlen(s)); //?

    char c = '\x12';
    printf("c = %d\n", c);

    return 0;
}

4: const 关键字

1、const 中文含义 常量,常属性

2、该关键字是一个变量的存储格式,修饰变量时,表示给该变量添加常属性

3、const修饰的变量,虽然有常属性,但是,还依然是一个变量

4、定义变量的格式 const 数据类型 变量名;

5、修饰变量时,包括修饰普通变量和指针变量,有所不同

#include<myhead.h>

int main(int argc, const char *argv[])
{
    int num = 520;       //定义的是普通变量
    const int key ;   //定义的是常变量

    //常变量跟普通变量一样,可以被访问
    printf("num = %d, key = %d\n", num, key);

    num = 999;
    //key = 666;   //不能直接通过key对key的值进行修改
    int *ptr = &key;
    *ptr = 666;
    printf("num = %d, key = %d\n", num, key);

    return 0;
}

6> const修饰指针变量(重要)

定义指针变量的格式: 数据类型 * 指针名;

#include<myhead.h>

int main(int argc, const char *argv[])
{
    int num = 520;
    int key = 1314;

    //定义指针变量指向普通变量
    const int *p1 = &num;    //p1保护的是指针指向内存空间中的值
    int const *p2 = &num;    //与p1一样
    int * const p3 = &num;   //p3保护的是指针中的值
    const int * const p4 = &num; //两个都保护

    //验证p1保护哪个内容
    //*p1 = 999;           //更改指针指向内存空间中的值,报错
    //p1 = &key;           //更改指针的值
    
    //验证p2保护哪个内容
    //*p2 = 999;           //更改指针指向内存空间中的值,报错
    // p2 = &key;           //更改指针的值

    //验证p3保护哪个内容
    //*p3 = 999;           //更改指针指向内存空间中的值,报错
    // p3 = &key;           //更改指针的值

    //验证p4保护哪个内容
    *p4 = 999;           //更改指针指向内存空间中的值,报错
    p4 = &key;           //更改指针的值


    return 0;
}

作业

1> 自定义函数(my_strlen)实现strlen函数的功能

//1>    自定义函数(my_strlen)实现strle
#include<stdio.h>
int my_strlen(char *arr)
{   
    int n;
    while(*arr++)
    {
        n++;
    }
    return n;
}

int main(int argc, char const *argv[])
{   
    char str[100]={};
    printf("请输入一个字符串:");
    scanf("%s",str);
    printf("%d\n",my_strlen(str));
    return 0;
}

2> 自定义函数(my_strcpy)实现strcpy函数的功能

//2>    自定义函数(my_strcpy)实现strcpy函数的功能
#include<stdio.h>
void my_strcpy(char *src,const char *dest)
{
    char temp = 0;

    //遍历所有src中的字符
    while(temp = *dest++)
    {
        *src++ = temp++;
    }
    *src = '\0';          
}



int main(int argc, char const *argv[])
{   
    char str[100]={""};
    char arr[100]={""};
    printf("请输入一个str字符串:");
    scanf("%s",str);
    printf("请输入一个arr字符串:");
    scanf("%s",arr);
    my_strcpy(str,arr);
    printf("%s\n",str);
    return 0;
}

3> 自定义函数(my_strcmp)实现strcmo函数的功能

//3>    自定义函数(my_strcmp)实现strcmo函数的功能
#include<stdio.h>

int my_strcmp(const char *arr,const char *brr)
{

    char temp = 0;

    //遍历所有src中的字符
    while(temp = *arr++)
    {
        if (*brr > temp)
        {
            return -1;
        }else if (*brr < temp)
        {
            return 1;
        }
        else
        {
            *brr++;
        }
        
    }
    return 0;
}








int main(int argc, char const *argv[])
{   
    char str[100]={""};
    char arr[100]={""};
    printf("请输入一个str字符串:");
    scanf("%s",str);
    printf("请输入一个arr字符串:");
    scanf("%s",arr);
    printf("%d\n",my_strcmp(str,arr));
    return 0;
}

4> 自定义函数(my_strcat)实现strcat函数的功能

//4>    自定义函数(my_strcat)实现strcat函数的功能
#include<stdio.h>

void my_strcat(char *arr,const char *brr)
{
    char temp = 0;

    //遍历所有arr中的字符
    while(*arr)
    {
        *arr++;
    }
        while(temp = *brr++)
    {
        *arr++ = temp++;
    }
    *arr = '\0'; 
}

int main(int argc, char const *argv[])
{   
    char str[100]={""};
    char arr[100]={""};
    printf("请输入一个str字符串:");
    scanf("%s",str);
    printf("请输入一个arr字符串:");
    scanf("%s",arr);
    my_strcat(str,arr);
    printf("%s\n",str);
    return 0;
}

5> 自定义函数(my_strstr)实现求src字符串中是否包含子串dest字符串

// 5>    自定义函数(my_strstr)实现求src字符串中是否包含子串dest字符串
#include <stdio.h>

char *my_strstr(const char *src, const char *dest)
{
    // 初始化三个字符指针:s1,s2和stu,其中stu初始指向src的首地址
    char *s1 = NULL;
    char *s2 = NULL;
    char *str = (char *)src;

    // 特殊情况:如果dest为空字符串(只包含结束符'\0'),则返回src的首地址
    if (*dest == '\0')
    {
        return (char *)src;
    }

    // 主循环,遍历字符串src直到遇到结束符'\0'
    while (*str)
    {
        // 将s1和s2分别复位
        s1 = str;
        s2 = (char *)dest;

        // 内部循环,逐个比较s1和s2指向的字符,如果相同则继续比较下一个字符
        // 直到遇到任意一个字符串的结束符'\0'或者发现不相等的字符为止
        while (*s1 && *s2 && (*s1 == *s2))
        {
            s1++;
            s2++;
        }

        if (*s2 == '\0') // 如果s2已经指向结束符'\0',则说明在stu开始的位置找到了子串dest,返回stu
        {
            return str; // 找到子串dest
        }

        if (*s1 == '\0') // 如果s1已经指向结束符'\0',说明当前stu所在子串长度不足以匹配dest,终止本次查找
        {
            return NULL;
        }

        *str++; // 移动stu指针,使其指向下一个可能的子串起始位置
    }

    // 遍历结束后仍未找到子串dest,则返回NULL
    return NULL; // 没找到
}

int main(int argc, char const *argv[])
{
    char str[100] = {""};
    char arr[100] = {""};
    printf("请输入一个str字符串:");
    scanf("%s", str);
    printf("请输入一个arr字符串:");
    scanf("%s", arr);
    printf("%s\n", my_strstr(str, arr));
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值