C语言-指针三

一. 二级指针

二级指针传参:在函数传参时:char *str char **str是等价的,类型兼容的

数组名在进行传参时都会降级为指针,故:char *str char **str等价

cpp 复制代码
void show_str1(char *str[], int size)
{
    int i = 0;
    for(i = 0; i < size; i++)
        printf("%d %s\n",i,str[i]);
}
void show_str2(char **str, int size)
{
    int i = 0;
    for(i = 0; i < size; i++)
        printf("%d %s\n",i,*(str+i));
}
int	main(int argc, char **argv)
{
    char *str[5] = {"apple","happy","how","are","you"};
    int size = sizeof(str) / sizeof(str[0]);
    //show_str1(str, size);
    show_str2(str, size);
    return 0;
}

二. main函数参数

argc: 命令行参数个数
argv: 命令行参数的具体内容

cpp 复制代码
int	main(int argc, char **argv)
{
    //argc 命令行参数个数
    //argv 命令行参数的具体内容

    return 0;
}

eg:使用命令行来完成两数相加

cpp 复制代码
#include <stdio.h>
#include<stdlib.h>

int	main(int argc, char **argv)
{
    //argc 命令行参数个数
    //argv 命令行参数的具体内容
    printf("argc is %d\n",argc);
    int i = 0;
    for(i = 0; i < argc; i++)
        printf("argv[%d] is %s\n",i,argv[i]);
//完成两数相加
    //当命令行传参个数不够时打印错误信息提醒用户
    // if(argc < 3)
    // {
    //     printf("Usage:%s num1 num2\n",argv[0]);
    //     return 1;
    // }
    // int sum = atoi(argv[1]) + atoi(argv[2]);
    // printf("sum = %d\n",sum);

//完成多数相加
    if(argc < 3)
    {
        printf("Usage:%s num1 num2...\n",argv[0]);
        return 1;
    }
    int sum = 0;
    for(i = 0; i < argc; i++)
        sum += atoi(argv[i]);

    printf("sum = %d\n",sum);

    return 0;
}

atoi函数:

作用:函数会将 `nptr` 指向的字符串的开头部分转换为整数。

返回值:返回转换后的值

三. 指针常量与常量指针

3.1 指针常量

指针常量:指针的指向可以改变,但是不能通过指针修改指针指向的数据。

cpp 复制代码
int	main(int argc, char **argv)
{
    char str[10] = "happy";
    char str2[10] = "apple";
    const char *p = NULL;//指针常量:指针指向可以改变,指针指向的数据不能改变,只读
    //char const *p = NULL; //这样也是一个指针常量,const修饰*p,只要const在*p的左边即可

    p = str;//指针的指向可以改变
    //p[0] = 'b'; //指针指向的数据不能改变

    return 0;
}

3.2 常量指针

常量指针:指针的指向不可以改变,但是可以通过指针修改指针指向的数据。

cpp 复制代码
int	main(int argc, char **argv)
{
    char str[10] = "happy";
    char str2[10] = "apple";

    char * const p2 = str;//常量指针:指针的指向不能改变,指针指向的数据可以改变
                          //const修饰p2,const处在p2的左边
                          //注意:常量指针一定要初始化
    p2[0] = 'b';//可以通过指针修改指针指向的数据可以
    //p2 = str2;//指针的指向不能改变

    char a[5] = "hhh";//数组名本质就是一个常量指针
    a[0] = 'b';//可以通过指针修改指向的数据
    //a++;//但是不能修改指针的指向

    const char* const p3 = str;//都不能改变,指向常量的常量指针

    return 0;
}

四. void类型指针

void类型修饰指针 :万能指针,可以接收任意类型指针作为参数在被调函数中。其他类型的指针

(char*,int*,double*short*,结构体指针等)传参到void*类型指针,直接传递参

数,即可。

当需要使用void*指针时,要对其进行强制类型转换。

void*类型的指针,存储着实参传递过来的地址,但是不能进行解引用操作,因

为没有void类型的变量。

可以用来修饰函数的返回值,或者参数。

memcpy函数的实现:

cpp 复制代码
int show_array(int *a, int size)
{
    int i = 0;
    for(i = 0; i < size; i++)
        printf("%d ",*(a + i));
    puts("");

    return 0;
}

void show_char_array(char *a)
{
  while (*a)
  {
    printf("%c", *(a++));
  }
  puts("");
}

// void *my_memcpy(void *dst, const void *src, size_t size)
// {
//     void *ret = dst;
//     while(size--)
//         *((char*)dst++) = *((char*)src++);

//     return ret;
// }

void *my_memcpy(void *dst, const void *src, size_t size)
{
    char *pdst = (char*)dst;
    char *psrc = (char*)src;
    while(size--)
        *pdst++ = *psrc++;
    return dst;
}

void* my_memmove(void* dst, const void* src, size_t num)
{
	void* ret = dst;
	if (src >= dst)//src在dst后面(或同地址),从前向后拷贝,不会覆盖
	{
		while (num--)
			*((char*)dst++) = *((char*)src++);
	}
	else//dst在src后面 → 从后向前拷贝,防止重叠覆盖
	{
        while(num--)
			*((char*)dst+num) = *((char*)src+num);
	}
	return ret;
}

int	main(int argc, char **argv)
{
    int a1[9] = {1,2,3,4,5,6,7,8,9};
    int a2[9] = { 0 };
    char str1[10] = "hello lll";
    char str2[10] = { 0 };
    // my_memcpy(a2,a1,sizeof(int)*10);
    // show_array(a2,10);
    // my_memcpy(str2, str1, sizeof(str1));
    // show_char_array(str2);

    // my_memmove(a2,a1,sizeof(int)*9);
    // show_array(a2,9);
    
    my_memmove(a1+2,a1,sizeof(int)*4);
    show_array(a1,9);

    return 0;
}
相关推荐
caimouse2 小时前
reactos编码规范
c语言·开发语言
小雨下雨的雨4 小时前
井字棋AI机器人实现详解 - Minimax算法实战-鸿蒙PC Electron框架完成
前端·人工智能·算法·华为·electron·鸿蒙
xieliyu.7 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
一条小锦吕*7 小时前
基于Spring Boot + 数据可视化 + 协同过滤算法的推荐系统设计与实现(源码+论文+部署全讲解)
spring boot·算法·信息可视化
AI thought8 小时前
【转】C语言中 -> 是什么意思?
c语言·位移运算符·右移赋值·无符号整数·算术右移
如竟没有火炬9 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
8Qi89 小时前
LeetCode 1143 & 718:最长公共子序列 / 最长重复子数组
算法·leetcode·职场和发展·动态规划
绿算技术9 小时前
万卡推理集群存储选型分析:从核心架构到应用视角
大数据·科技·算法·架构
想吃火锅100510 小时前
【leetcode】1.两数之和js版
javascript·算法·leetcode