复习第七课 C语言-指针数组,函数,string

news2024/12/25 9:16:09

目录

【1】指针和数组

【2】数组指针

【3】指针数组

【4】函数

【5】函数传参

【6】动态开辟堆区空间

【7】string函数族

【8】递归函数

练习:


【1】指针和数组

直接访问:通过数组名访问

间接访问:通过指针访问

》1. 一维数组

int a[5]={1,2,3,4,5};
int * p = a;

直接访问:
访问a[i]的地址:
&a[i]    a+i
访问a[i]的值:
a[i]   *(a+i)


间接访问:
访问a[i]的地址:
&p[i]    p+i
访问a[i]的值:
p[i]   *(p+i)

int a[5] = {1,2,3,4,5};
int *p=a;
printf("%d",*p++);//1
printf("%d",*a++);//报错

运算方法:

1) *和++都是弹幕运算符,优先级相同

2) 单目运算符从右向左运算

*p++	:先取*p,然后p自加
*(p++)	:先取*p,然后p自加
(*p)++	:先取*p,然后*p自加

++*p	:先取*p,然后*p自加
++(*p)	:先取*p,然后*p自加
*++p	:先p自加,然后取自加后的*p
*(++p):先p自加,然后取自加后的*p

》2. 二维数组

int a[2][3]={1,2,3,4,5,6};
a:第一行的首地址
a+1:第二行的首地址

*:降级
*行地址:表示将行地址降级成列地址

*a:第一行第一列的地址
*a+1:第一行第二列的地址
*(a+1):第二行第一列的地址

访问a[i][j]的地址:
a[i]+j     *(a+i)+j

访问a[i][j]的值:
*(a[i]+j)    *( *(a+i)+j)

【2】数组指针

1. 定义:

指向数组的指针,本质的指针(又称行指针)

2. 格式:

存储类型 数据类型 (* 指针名)[列数];

int a[2][3]={1,2,3,4,5,6};
int (*p)[3]=a;//int (*)[3]   p

3. 间接访问:

访问a[i][j]的地址:
*(p+i)+j     p[i]+j

访问a[i][j]的值:
*(*(p+i)+j )   *( p[i]+j)

4. 大小:

sizeof(p)=4字节 (32位操作系统)

【3】指针数组

1. 定义:

本质是数组,里面存放的是指针

2. 格式:

3.应用实例:

1)用于存放普通变量的地址
int a = 10,b=20,c=30;
int *p[3]={&a,&b,&c};
访问b的地址
p[1]		*(p+1)
访问b的值
*p[1]		*(*(p+1))

2)用于存放二维数组每行第一列的地址
int a[2][3]={1,2,3,4,5,6};
int * p[2]={a[0],a[1]};
访问a[1][2]的地址:
p[1]+2   *(p+1)+2   
访问a[1][2]的值:
*(p[1]+2)   *(*(p+1)+2)
sizeof(p)=8;//p是数组,包含两个指针

3)用于存放字符串
char *p[3]={"hello","world","hqyj"};
打印字符串world
printf("%s\n",p[1]);
printf("%s\n",*(p+1));
打印字符串world里面的字符d
printf("%c\n",*(p[1]+4));
printf("%c\n",*(*(p+1)+4));

4)命令行传参
int main(int argc, char const *argv[])
{
	return 0;
}
argv:指针数组,存放命令行输入字符串的首地址
argc:表示argv存储数据的个数

【4】函数

【4】函数

1. 定义:

一个完成特定功能的代码模块

2. 格式:

存储类型	   数据类型    函数名(参数列表)
{
	函数体;
	return 表达式;
}

1) 没有参数:参数列表可以省略(也可以写void)

2) 没有返回值:数据类型为void,函数内部省略return语句

3) 有返回值:需要根据返回值的类型定义函数的数据类型

#include<stdio.h>
void fun( )//无参无返回值
{
    printf("hello world!\n");
}

void add(int a,int b)//有参无返回值
{
    printf("%d\n",a+b);
}

int sub(int a,int b)//有参有返回值
{
    return a-b;
}

int main(int argc, char const *argv[])
{
    fun();//函数调用
    add(3,4);//7
    int t =sub(9,5);//4
    printf("%d\n",t);
    return 0;
}
 

注意:

函数可以直接定义在被调用位置前,也可以定义在被调用位置后面,但是必须要提前声明函数,函数声明就是将函数第一行复制到上面加;

3. 函数声明:

数据类型 函数名(形参);

4. 函数三要素:

功能、参数、返回值

5. 函数调用:

1) 没有返回值:直接调用:函数名(实参);

2) 有返回值:如果需要返回值,定义一个和返回值类型相同的变量来接收;如果不需要接收返回值,就可以直接调用

练习:

1.已知字符数组a[10]和b[10]已知字符数组a[10]和b[10]中元素的值递增有序,用指针实现将两个数组中元素按照递增顺序输出。

如:char a[10]=”acdgjmno”; char b[10]=”befhil”;->”abcdefghijlmno”

#include<stdio.h>
int main(int argc, char const *argv[])
{
    char a[10]="acdgjmno";	
    char b[10]="befhil";
    char * p = a;
    char * q = b;
    while (*p && *q)
    {
        if(*p < *q)
        {
            printf("%c",*p);
            p++;
        }
        else
        {
            printf("%c",*q);
            q++;
        } 
    }
    if(*p == '\0'&& *q)
        printf("%s\n",q);
    else if(*q == '\0' && *p)
        printf("%s\n",p);
    return 0;
}
 

2.编写一个函数,函数的2个参数,第一个是一个字符,第二个是一个char *,返回字符串中该字符的个数。

#include <stdio.h>

int countChar(char c, char *str) {
    int count = 0;
    while (*str != '\0') {
        if (*str == c) {
            count++;
        }
        str++;
    }
    return count;
}

int main() {
    char str[] = "Hello, World!";
    char c = 'o';
    int count = countChar(c, str);
    printf("The character '%c' appears %d times in the string.\n", c, count);
    return 0;
}
 

【5】函数传参

1)值传递

单向传递,将实参传递给形参,修改形参,实参不会受影响

2)地址传递

双向传递,在函数中修改形参,实参会随之变化

3)数组传递

和地址传递一样,参数中存在数组定义,但是会认为是指针

练习:封装函数实现两个数的交换

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int num1 = 10;
    int num2 = 20;
    printf("Before swap: num1 = %d, num2 = %d\n", num1, num2);
    swap(&num1, &num2);
    printf("After swap: num1 = %d, num2 = %d\n", num1, num2);
    return 0;
}
 

【6】动态开辟堆区空间

头文件:#include <stdlib.h>
void *malloc(size_t size);
功能:在堆区开辟空间
参数:
size:开辟空间大小(字节)
返回值:
成功:返回开辟堆区空间首地址
失败:NULL

void free(void *ptr);
功能:释放堆区空间
参数:
ptr:开辟堆区空间首地址
返回值:无
int * p =(int *)malloc(sizeof(int)*10);
if( p == NULL)
{
	printf("p malloc err\n");
	return -1;
}
for(int i=0;i<5;i++)
*(p+i)=i;
free(p);
p=NULL;

总结:

1. 在使用手动开辟堆区空间时,要注意内存泄漏当指针指向开辟堆区空间首地址时,又对指针赋值,则没有指针指向开辟的堆区空间会导致内存泄漏

2. 使用完堆区空间及时释放

【7】string函数族

头文件:#include <string.h>

1.strcpy
char *strcpy(char *dest, const char *src);
功能:实现字符串复制
参数:  
dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
注意:
复制整个字符串,包括\0
char *strncpy(char *dest, const char *src, size_t n);
复制字符串的前n个字符

2.strcat	
char *strcat(char *dest, const char *src);
功能:用于字符串拼接
参数:
dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
char *strncat(char *dest, const char *src, size_t n);
拼接字符串的前n个字符

3.strcmp	
int strcmp(const char *s1, const char *s2);
功能:字符串的比较
参数:
s1,s2:两个字符串的首地址
返回值:
比较首个不同的字符的ASCII值,数小的字符串就小
0		s1 == s2
1		s1>s2
-1		s1<s2
int strncmp(const char *s1, const char *s2, size_t n);
比较两个字符串的前n个字符

【8】递归函数

1. 定义 :

自己调用自己

2. 执行过程分为两个阶段:

递推阶段:从原问题出发,按递归公式递推从未知到已知,最终达到递归终止条件

回归阶段:按递归终止条件求出结果,逆向逐步带入递归公式,回归到原问题求解

练习:

输入一个字符串,内有数字和非数int字符,如a123x456,将其中连续的数作为一个整数,依次存放到整形数组a中。

例:123存放在a[0],456存放在a[1]。统计共有多少整数,并输出这些整数。

#include <stdio.h>

int main() {
    char str[] = "a123x456";
    int a[10];  // 假设整型数组大小为10
    int count = 0;  // 统计整数个数
    char temp[20];  // 临时字符串,用于存放连续的数字字符
    int index = 0;  // 当前存放整数的数组下标

    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] >= '0' && str[i] <= '9') {
            temp[index++] = str[i];
        } else {
            if (index > 0) {
                temp[index] = '\0';  // 添加字符串结束符
                a[count++] = atoi(temp);  // 将临时字符串转换为整数并存放到数组中
                index = 0;  // 重置临时字符串下标
            }
        }
    }
    printf("共有%d个整数:\n", count);
    for (int i = 0; i < count; i++) {
        printf("a[%d] = %d\n", i, a[i]);
    }
    return 0;
}

                

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757657.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态规划之118杨辉三角(第6道)

题目&#xff1a;给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 题目链接&#xff1a;118. 杨辉三角 - 力扣&#xff08;LeetCode&#xff09; 示例&#xff1a; 解法&#xff1…

【iOS】内存管理五大区

参考博客&#xff1a;iOS内存管理学习第一篇-内存五大区 3.1 OC特性之 内存五大区域 1. 简述 程序要想执行&#xff0c;第一步就需要 被加载到内存中 内存五大区域: 栈区,堆区,BSS段(静态区),常量区(数据段),代码段. 栈区&#xff08;stack&#xff09;由编译器自动分配并释放…

手写Spring框架---MVC实现

目录 预备 自研框架MVC的实现 MVC架构草图&#xff1a; 大致流程 实现思路 自定义注解 JavaBean 请求的拦截-建立DispatcherServlet 责任链处理请求 RequestProcessor矩阵 Render矩阵 预备 在DispatcherServlet&#xff1a; 解析请求路径和请求方法依赖容器&#xf…

最全的 Spring 依赖注入方式,你都会了吗?

Spring 正如其名字&#xff0c;给开发者带来了春天&#xff0c;Spring 是为解决企业级应用开发的复杂性而设计的一款框架&#xff0c;其设计理念就是&#xff1a;简化开发。 Spring 框架中最核心思想就是&#xff1a; IOC&#xff08;控制反转&#xff09;&#xff1a; 即转移…

ChatGPT 最佳实践指南之:使用外部工具

Use external tools 使用外部工具 Compensate for the weaknesses of GPTs by feeding them the outputs of other tools. For example, a text retrieval system can tell GPTs about relevant documents. A code execution engine can help GPTs do math and run code. If a …

45、Spring Boot自动配置原理

Spring Boot自动配置原理 lmport Configuration Spring spi 自动配置类由各个starter提供&#xff0c;使用Configuration Bean定义配置类&#xff0c;放到META-INF/spring.factories下使用Spring spi扫描META-INF/spring.factories下的配置类使用lmport导入自动配置类

通讯录管理系统--进阶(动态开辟内存+保存数据到文件)

文章目录 动态开辟内存优化改进通讯录类型改进初始化通讯录函数改进添加联系人的函数增加销毁通讯录信息的函数 保存数据到文件优化保存通讯录数据到文件读取数据到通讯录 完整的代码展示 在 C语言实现通讯录的所有基本功能详细代码分析中&#xff0c;我们已经实现了通讯录的基…

Linux系统编程:文件系统和inode

目录 一. 磁盘的结构和读写数据的方式 1.1 磁盘级文件和内存级文件 1.2 磁盘的物理结构 1.3 访问磁盘数据的方式 二. 磁盘文件系统 2.1 磁盘的分区管理方法 2.2 文件名和inode的关系 三. 结合文件系统对文件创建和删除的相关问题的理解 3.1 文件创建时操作系统进行的工…

如何给合宙ESP32-C3刷写arduino固件,arduinoIDE的配置,测试代码

视频教程 https://github.com/Yu-1120/ESP32-C3 资料下载地址 合宙ESP32-C3刷写arduino固件 然后点击安装就可以了 arduino-IDE的配置 我用的版本&#xff1a;2.1.1&#xff08;版本不对也多大没关系&#xff09; 下载安装 选择 ESP32C3 Dev Module 安装环境 配置环境&am…

二十六、传输层协议(下)

一、滑动窗口 刚才我们讨论了确认应答策略&#xff0c;对每一个发送的数据段&#xff0c;都要给一个ACK确认应答. 收到ACK后再发送下一个数据段。这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候. 既然这样一发一收的方式性能较低, 那么我们一次发送…

snpEff注释结果解读

目录 1.帮助文档 1.1 常用参数 2. 命令的用法&#xff1a; 3. 结果文件解读 4. SNP下游的分析 利用snpEff软件对 snp.vcf &#xff08;利用gatk软件calling-snp&#xff09;进行注释&#xff0c;运行下述命令&#xff1a; ## 构建好物种的数据库 java -jar /opt/snpEff/s…

基于Spring Boot的扶贫助农商城系统设计与实现(Java+spring boot+MySQL+VUE)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的扶贫助农商城系统设计与实现&#xff08;Javaspring bootMySQLVUE&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java spr…

QTranslator语言转换

//appname的格式 例如通常为&#xff08;QQ为应用的名称&#xff09; QQ_en.ts或QQ_zh_CN.ts QString qmName"zh_CN"; QTranslator trans ; QString qm QString(":/translatoin/qt/appname_%1.qm").arg(qmName); auto ret trans.load(qm); Q_UNUSED(ret)…

CSS高级特性

1.CSS复合选择器 CSS复合选择器&#xff1a;复合选择器是由两个或多个基础选择器通过不同的方式组合而成的 1.1 标签指定式选择器&#xff1a;又称交集选择器&#xff0c;由两个选择器构成&#xff0c;其中第一个选择器为标记选择器&#xff0c;第二个为class选择器或id选择器…

【Spring core学习一】简单认识Spring是什么?

目录 1、为什么要学习Spring&#xff1f; 2、Spring是什么&#xff1f; 1、IoC是什么&#xff1f; 2、进一步通过代码演示理解IoC 3、怎么理解容器&#xff1f; 4、知道DI与IoC的区别&#xff1f; 1、为什么要学习Spring&#xff1f; 我们常说的Spring 指的是 Spring Fra…

地平线旭日x3派40pin引脚控制,点亮小灯,控制舵机

地平线旭日x3派40pin引脚控制&#xff0c;点亮小灯&#xff0c;控制舵机 引脚对照表点亮RGB小灯安装旭日X3派WiringPi使用WiringPi点亮RGB小灯使用软件PWM功能 官方用户手册中只有python控制教程&#xff0c;没有c语言控制教程。且官方的教程中并没有软件pwm功能。本教程在开发…

Linux——动静态库的制作和使用(实操+代码+原理介绍)

动静态库的制作和使用 1️⃣.动静态库介绍&#x1f3c0;静态库⚽️动态库&#x1f3c8;区别&#x1f3d0;使用动态库的优点包括&#xff1a;&#x1f3c9; 使用静态库的优点包括&#xff1a; 2️⃣静态库的制作&#x1f34a;Q:库文件能不能有main()函数&#xff1f;&#x1f34…

imazing是什么软件?2023年imazing官网中文版下载

最近很小伙们&#xff0c;咨询兔八哥&#xff0c;imazing是什么软件&#xff1f;&#xff0c;今天兔八哥爱分享整理一下imazing到底是什么软件&#xff1f;好用吗&#xff1f; imazing是一款iOS设备管理软件,借助 iMazing 的独有 iOS 备份技术&#xff08;无线、隐私和自动&am…

地震正演基础知识

文章目录 地震正演1. 地震正演基础知识1.1 地震波1.2 波动方程1.3 有限差分方法1.4 边界条件1.5 记录数据 2. 公式2.1 泰勒级数回顾2.2 二维声波方程&#xff08;连续的偏微分方程&#xff09;2.2.1 二维声波方程&#xff08;连续的偏微分方程&#xff09;2.2.2 离散化二维声波…

【C++】vector模拟实现

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…