2023/7/20 -- C语言基础

作业:

  1. 使用数组作为参数传递,完成一维数组的输入和输出,写两个函数,一个输入一个输出。
  2. 定义一个字符数组,作为参数传递,完成strlen函数的功能,定义一个int my_strlen(const char *p){}
  3. 整理思维导图
  4. 使用指针指向字符串的方式,写一个函数完成删除字符串中的空格
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int m = 10;
    int n = 20;
    
    //功能:实现 p 指向的地址的值变为 n 的地址
    int myfunc1(int **q){
    	int temp = 0;
    	*q = &n;
    }
    
    //功能:实现两个数 值 的交换
    void swap(int *p1,int *p2){
    	int temp = 0;
    	temp = *p1;
    	*p1 = *p2;
    	*p2 = temp;
    }
    
    //功能:实现一维数组的终端输入
    void myfunc2(int *p,int len){
    	int i = 0;
    	for(i = 0;i < len;i++){
    		scanf("%d",p+i);
    	}
    	for(i = 0;i < 5;i++){
    		printf("%d\t",p[i]);
    	}
    	printf("\n");
    }
    
    //功能:实现strlen功能,计算字符串的长度
    int my_strlen(const char *p){
    	int count = 0;
    	while(*p){
    		count++;
    		p++;
    	}
    	return count;
    }
    
    //功能:删除字符串中的空格
    void myfunc3(char *p){
    	int i = 0;
    	int count = 0;
    	int len = strlen(p);
    	while(*(p+i)){
    		i++;
    	}
    	for(i = 0;i < len;i++){
    		if(*(p+i) != ' '){
    			*(p+count) = *(p+i);
    			count++;
    		}
    	}
    	*(p+count) = *(p+i);
    }
    
    int main(int argc, const char *argv[])
    {
    
    #if 0
    	int *p = &m;
    	printf("p = %p &m = %p\n",p,&m);
    	myfunc1(&p);
    	printf("p = %p &n = %p\n",p,&n);
    #endif
    
    #if 0
    	int a = 10;
    	int b = 20;
    	printf("a = %d b = %d\n",a,b);
    	swap(&a,&b);
    	printf("a = %d b = %d\n",a,b);
    #endif
    
    #if 0
    	int arr[5] = {0};
    	myfunc2(arr,5);
    #endif
    
    #if 0	
    	char s1[32] = "hello world";
    	int ret = my_strlen(s1);
    	printf("strlen(s1) = %d\n",ret);
    #endif
    
    #if 1
    	char s2[32]= {0};
    	gets(s2);
    	myfunc3(s2);
    	puts(s2);
    #endif
    
    	return 0;
    }
  5. 猴子吃桃问题,猴子第一天摘了若干个桃,当即就吃了一半数量的桃,没吃过瘾,又多吃一个,第二天,在剩下的桃里有吃了一半数量的桃,没吃过瘾,又多吃了一个,依此类推,直到第10天,想吃桃的时候,发现只剩下一个桃了,问:猴子第一天摘了多少个桃。while循环实现
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, const char *argv[])
    {
    	int num = 1;
    	int day = 1;
    	while(day < 10){
    		num = 2 * (num + 1);
    		day++;
    	}
    	printf("num = %d\n",num);
    	return 0;
    }
  6. 实现atoi函数
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(int argc, const char *argv[])
    {
    	char s[32] = {0};
    	gets(s);
    	char *p = s;
    	int num = 0;
    	while(*p){
    		num *= 10;
    		num += *p - '0';
    		p++;
    	}
    	printf("%d\n",num);
    	return 0;
    }
  7. 整理函数的值传递和地址传递 画图理解

一、函数

面向对象语言:C++,封装性好

面向过程语言:C语言,封装性更差一些,代码的复用性差

函数在C语言中,提高代码的复用性。

【1】概念

函数:指的是实现特定功能的代码块。

【2】定义

返回值类型 函数名(形式参数列表)
{
    //实现函数功能的代码块;
    return 返回值;
}

返回值类型,决定了函数返回的结果;函数的返回值可以有,也可以没有,如果返回值类型是void,可以不写return

函数名:也是一个标识符,给函数起的名字(写什么都可以)
(形参列表):用于获取外部传递过来的参数的,函数是否有形参,根据函数功能来决定,如果没有形参,()中可以什么都不写,也可以写void
返回值:函数运行结束,返回给调用处的结果,根据函数的需求,如果调用函数的位置需要返回值,在函数内部就需要写返回值
如果调用处不需要返回值,返回值类型可以写成void

【3】函数的分类

i)有参有返回值函数
//实现有参有返回值的加法函数
//返回加法的结果
int add(int a,int b)
{
    return a+b;
}
ii)有参无返回值函数
//有参无返回值函数
void mul(int a,int b)
{
    printf("mul=%d\n",a*b);
}
iii)无参无返回值函数
//无参无返回值函数
void fun()
{
    printf("1\n");
}
iv)无参有返回值函数
//无参有返回值函数
int my_getchar()
{
    return getchar();
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//实现有参有返回值的加法函数
//返回加法的结果
int add(int a,int b)
{
    return a+b;
}

//有参无返回值函数
void mul(int a,int b)
{
    printf("mul=%d\n",a*b);
}

//无参无返回值函数
void fun()
{
    printf("1\n");
}

//无参有返回值函数
int my_getchar()
{
    return getchar();
}

int main(int argc, const char *argv[])
{
    printf("%d\n",add(3,5));
    mul(2,4);
    fun();
    char c = my_getchar();
    printf("%c\n",c);
    return 0;
}

【4】函数的调用

在其他函数中使用功能函数

函数名(实参); 
//如果函数没有参数列表()里面的内容不写

【5】函数的声明

函数声明的时机: 如果被调函数定义在主调函数的下方,由于程序顺序执行,在调用时并没有定义过被调函数
程序会报警告,再调用函数前,添加函数的声明就可以消除警告

函数声明的格式:
返回值类型 函数名(形参的类型);
简单的办法:直接把定义函数的函数头拿到主调函数上方

函数声明的作用:告诉编辑器,已经定义过该函数,还要告诉编辑器函数的返回值类型和形参类型

函数声明的位置:头文件的下方,主调函数的上方(保证在调用之前声明过该函数)

【6】全局变量和局部变量

全局变量:没有定义在任何函数内的变量(没有被包在任何{}里面的变量)

全部变量:定义在函数中的变量

全局变量和局部变量,生命周期和作用域是不同的

生命周期:分配的空间何时被回收,变量的开始到消亡

作用域:可以访问的范围

存储类型:6种
auto:局部变量默认是auto,全局变量不能使用auto修饰
static:修饰局部变量时,延长局部变量的生命周期
       修饰全局变量时,限制全局变量只能在当前文件中被访问
       static修饰的变量只会被初始化一次
extern: 引入外部文件种的变量 
register:
const:一般不对const修饰的变量取地址
volatile:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//auto int num = 90;  error全局变量不能使用auto修饰

static int num = 90;  //全局变量的生命周期和作用于是整个程序的开始到结束
int num2;   //静态区中, .bss段中
int fun();
void out();   //外部文件中函数的声明
int main(int argc, const char *argv[])
{
    auto int sum=100;
    //main里面的sum是局部变量,但是由于main函数是程序的入口,定义在main函数中变量的生命周期和全局变量的一样长
    //作用域只能在主函数内被访问
    
    int ret1 = fun();  //7
 int ret = fun();   //9
    printf("16=%d\t17=%d\n",ret1,ret);

    return 0;
}

int fun()
{
    int a;  //变量a的生命周期和作用于再fun函数内
    static int b; //变量b的生命周期是程序的开始到结束但是作用域仍然是fun函数内
    static int var = 5;  //static修饰的变量生命周期是程序开始到结束,所以static修饰的变量支部会被初始化一次
    int i=0;
    while(i<2)
    {
        i++;
        var++;
    }
    return var;

    //printf("%d\n",sum);  sum的作用域只在主函数中
}

【7】函数的值传递和地址传递

函数传参,就是使用实参初始化形参的过程。

i)值传递

值传递,单纯把实参的值传递给形参的过程

如果是指传递,函数内部无法修改实参的值

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int var1=80;
int var2=90;
int add(int a,int b);
void swap(int a,int b);  //swap的前置声明
int main(int argc, const char *argv[])
{
    int ret = add(var1,var2);  //全局传参
    printf("%d\n",ret);
    int num1=90,num2=39;
    printf("num1=%d\tnum2=%d\n",num1,num2);    //90,39
    swap(num1,num2);
    printf("num1=%d\tnum2=%d\n",num1,num2);     

    return 0;
}

int add(int a,int b)
{
    return a+b;
}
void swap(int a,int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}
ii)地址传递

地址传递,就是是用实参地址初始化形参

如果是地址传递,函数内可以改变实参的值

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int var1=80;
int var2=90;
int add(int a,int b);
void swap(int *a,int *b);  //swap的前置声明
int main(int argc, const char *argv[])
{
    int ret = add(var1,var2);  //全局传参
    printf("%d\n",ret);
    int num1=90,num2=39;
    printf("num1=%d\tnum2=%d\n",num1,num2);    //90,39
    swap(&num1,&num2);
    printf("num1=%d\tnum2=%d\n",num1,num2);     

    return 0;
}

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

【8】一维整形数组作为函数传参

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//一维整型数组作为参数传递,需要传数组的首地址,还要传数组的长度
//5没有任何含义,代码的自注释,给程序自己看数组有多长
//void fun(int p[5],int len)
void fun(int *p,int len)
{
    printf("%ld\n",sizeof(p));   //8,p就是一个指针,只是写成了数组的形式
    //arr的终端输入
    int i;
    for(i=0;i<len;i++)
    {
        scanf("%d",p+i);
    }
}
int main(int argc, const char *argv[])
{
    int arr[5];
    fun(arr,5);
    int i;
    for(i=0;i<5;i++)
    {
        printf("arr[%d]=%d\n",i,arr[i]);
    }
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值