2024.7.25 c语言学习 函数调用

表示符命名规则:

  1. 只能由英文字母,数字,下划线
  2. 首字母不能是数字,只能是字母和下划线
  3. 不能和系统关键字,用户已经定义好的函数以及系统库函数重名
  4. 下划线开头的一般是系统的函数名变量名,建议用户避免使用这类标识符。
  5. 大小写区分
  6. 见名知义

调式的几个单词

Step over :下一步

Step into :进入函数

Step out:从函数跳出来

Funto cursor:运行到光标外

函数调用:

 1,函数必须先声明再使用,如果函数定义在调用之前,

 可以不进行函数原型的声明。如果函数定义在调用之后,

 必须进行函数原型的声明。函数原型的声明是告诉编译器

 有这样的函数,函数参数有几个,参数类型是什么,返回值类型

 是什么,编译器就可以根据函数原型的声明,去检查函数调用

 的语法是否正确。

 2,函数返回值类型,函数运算完成后,返回的数值的类型

 调用者就可以根据函数返回值类型,定义相应类型的变量,

 来接收函数返回值,(当然,函数返回值也有可能是void)

 函数形参是调用时分配空间,接收实参值的。

 函数内部定义的变量叫局部变量,保存函数中间运算结果的。

 它的作用范围是本函数,不同函数可以定义相同名字的局部变量

 他们代表不同的内存,形参是被调用函数的局部变量。

 3,函数被调用时,产生栈帧,形参分配空间接收实参的值。函数调用完毕后

 栈帧自动释放(形参和局部变量分配的空间自动释放),不能返回局部变量

 的地址。

 4,必须按数目一样,类型一致,顺序一样的原则进行实参和形参的结合。

    这种数据传递是单向的,只能由实参传递给形参,

    而形参的改变不会影响到实参

(1)

#include <stdio.h>

int * get_sum(int a,int b);

int main() {

    int x = 0;

    int y = 0;

    scanf("%d%d",&x,&y);

    int * sum = get_sum(x,y);//函数调用 call

    printf("%d",*sum);

    return 0;

}

int * get_sum(int a,int b){  //定义,define

    int sum = 0;

    sum = a + b;

    return ∑

}

(2)

int  get_sum(int a,int b);

int main() {

    int x = 0;

    int y = 0;

    scanf("%d%d",&x,&y);

    int sum = get_sum(x,y);//函数调用 call

    printf("%d",sum);

    return 0;

}

int  get_sum(int a,int b){  //定义,define

    int sum = 0;

    sum = a + b;

    return sum;

}

(3)

nt  get_sum(int a,int b);

int main() {

    int a = 0;

    int b = 0;

    scanf("%d%d",&a,&b);//10 5

    get_sum(a,b);//函数调用 call

    printf("%d %d",a,b);

    return 0;

}

int  get_sum(int a,int b){  //定义,define

    a = 100;

    b = 50;

    return 0;

}

(4)

编写程序,将用户输入的字符串中所有的字符a去掉,然后输出剩余的字符。

void del_a(char * s){

    char * p = s;

    char * q = s;

    for(p = s;*p!='\0';p++){//遍历字符串呢。

        if(*p != 'a'){

            *q = *p;

            q++;

        }

    }

    *q = '\0';



}

int main(){

    char str[100] = {0};

    scanf("%s",str);

    del_a(str);

    printf("%s",str);

}

(5)

打印所有的水仙花数。所谓水仙花数是指一个三位数,其各位数字的立方和等于该数。例如,153就是一个水仙花数,因为153=1*1*1+5*5*5+3*3*3。

//我的想法,我想写个函数,用整数数组保存这些找到的水仙花数。

void fun(int * arr,int * pcnt){

    for(int i = 100;i<=999;i++){ //按每个数去实验

        int a = i%10;

        int b = i/10%10;

        int c = i/100;

        if(a*a*a + b*b*b + c*c*c == i){ //满足此条件就是水仙花数。

            arr[*pcnt] = i;//放到数组里。

            (*pcnt)++; //放完后,个数加1.

        }

    }

}

void out_flower_number(int * arr,int cnt) {

    for(int i = 0;i<cnt;i++){

        printf("%d ",arr[i]);

    }

}

int main(){

    int a[1000] = {0};//保存水仙花数的。

    int cnt = 0;//保存运算出来的水仙花数的个数的。

    fun(a,&cnt);

    out_flower_number(a,cnt);

}

(6)

一个皮球从100米高度自由落下,每次落地后反弹回原高度的一半,再落下,再反弹。求当它第10次落地时,共经过了多少米,第10次反弹多高?

float caculate(float * h){

    float init_h = 100;

    float sum= 0;

    for(int i = 0;i<10;i++){

        sum += init_h + init_h/2;

        init_h = init_h/2;//给下一次循环做准备。

    }

    sum -= init_h;

    *h = init_h;

    return sum;

}

int main(){

    float height = 0;//要想改变调用者变量的值,必须将变量的地址传递到被调用函数中。

    //被调用函数得到地址后,前面加*,就找到调用者的变量,就可以将其改变。

    float sum = caculate(&height);

    printf("sum = %.3f,height=%.3f",sum,height);

}

(6)

float caculate(float * h){

    float init_h = 50;

    float sum= 100;

    for(int i = 0;i<9;i++){

        sum += init_h * 2;

        init_h /=2;

    }

    *h = init_h;

    return sum;

}

int main(){

    float height = 0;//要想改变调用者变量的值,必须将变量的地址传递到被调用函数中。

    //被调用函数得到地址后,前面加*,就找到调用者的变量,就可以将其改变。

    float sum = caculate(&height);

    printf("sum = %.3f,height=%.3f",sum,height);

}

(7)

(1)

void fun(int * a,int n){

    (*a)++;

    (*a)++;

    (*a)++;

    (*a)++;

}

int main(){

    int a[10] = {1,2,3,4,5,6,7,8,9,10};

    fun(a,10);

    for(int i = 0;i<10;i++){

        printf("%d ",a[i]);

    }

}

(2)

void fun(int * a,int n){

    *a++;

    *a++;

    *a++;

    *a++;

}

int main(){

    int a[10] = {1,2,3,4,5,6,7,8,9,10};

    fun(a,10);

    for(int i = 0;i<10;i++){

        printf("%d ",a[i]);

    }

}

这两个的比较,得到结论,形参的改变不能影响到实参,但可以通过形参改变实参指向的内存块的值。

循环里用的两个关键字,continue,结束本次循环,Break:结束本层循环。

Continue:结束本次循环,下面代码不在执行,再次循环。

int main(){

    for(int i = 0;i<10;i++){

        if(i%2 == 0){

            continue;//结束本次循环。//下面代码不再执行,再次循环。

        }

        printf("%d ",i);

    }

}

Break:结束本层循环

   for(int i = 0;i<10;i++){

        if(i%2 == 0){

            break;//结束本层循环。

        }

        printf("%d ",i);

    }

}

/*输入10个数,判断10个数中,有没有偶数,如果有输出1,否则输出0*/

int fun(int * a,int n){

    int i = 0;

    for(i = 0;i<n;i++){

        if(a[i]%2==0){

            break;

        }

    }

    if(i<n){

        return 1;

    }

    return 0;

}

int main(){

    int a[10] = {0};

    for(int i = 0;i<10;i++){

        scanf("%d",&a[i]);

    }

    int k = fun(a,10);

    printf("%d",k);

}

/*给一个字符串,得到大写字母的个数,小写字母的个数,数字字符的个数,其它的字符的个数

 const char * str:

      str保存的是const char型内存块的地址,str可以改,str指向的内存块是const char型,是不能改的

 char * const str:

      str保存的是char型内存块的地址,const修饰了str,所以

      str不能改。str指向的内存块是可以改变的。

 const char * const str:

      都不能改了。

 * */

void fun( const char *  str,int * arr){

    for(int i = 0;str[i]!='\0';i++){

        if(str[i]>='A' && str[i]<='Z'){

            arr[0]++;

        }

        else if(str[i]>='a' && str[i]<='z'){

            arr[1]++;

        }else if(str[i]>='0' && str[i]<='9'){

            arr[2]++;

        }else{

            arr[3]++;

        }

    }

}

int main(){

    char str[100] = {0};

    int arr[4] = {0};//arr[0]:大写字母的个数,arr[1],小写字母的个数,arr[2]数字字符的个数,arr[3]其它的字符的个数

    scanf("%s",str);

    fun(str,arr);

    printf("大写字母的个数:%d\n"

           "小写字母的个数:%d\n"

           "数字字符的个数:%d\n"

           "其它的字符的个数:%d\n",arr[0],arr[1],arr[2],arr[3]);

    return 0;

}

格式化符

L/h

(最小宽度)m

-(负号)

#

前补0

结果

说明

整型

d

×

-6Ld

按有符号十进制

o

-#6Lo

按无符号8进制

x

-#6Lx

按无符号16进制

u

×

-6Lu

按无符号十进制

实型

L

m.n

-

f

%-6.2f

e

×

×

%-6.2e

字符和字符串

c

×

只有m

×

×

%-6d

s

×

×

×

%-6.2s

/*

 输入开始时间,和经过的时间段,输出最后时间。

 例如:

 输入:2:23:7 3:39:55

 输出:    06:03:02

 * */

void read_data(int * start,int * pass){

    while(1){

        printf("请按%%d:%%d:%%d %%d:%%d:%%d 格式输入数据:\n");

        int k = scanf("%d:%d:%d %d:%d:%d",

                      &start[2],&start[1],&start[0],

                      &pass[2],&pass[1],&pass[0]);

        if(k != 6){

            char buf[100] = {0};

            gets(buf);//把错误的数据读过去。让用户重新输入。

        }else{

            break;

        }

    }

}

#define MOD(a) ((a)==2?24:60)

void caculate(const int * start,const int * pass,int * end) {

    int carry = 0;

    int time = 0;

    for(int i = 0 ;i<3;i++){

        end[i] = ((time = start[i] + pass[i] +carry))%MOD(i);

        carry = time/MOD(i);

    }

}

int main(){

    int start[3] = {0};

    int pass[3] = {0};

    int end[3] = {0};

    read_data(start,pass);

    caculate(start,pass,end);

    printf("%02d:%02d:%02d\n",end[2],end[1],end[0]);

    return 0;

}



int main(){

    float a = 123.4567;

    printf("|%-10.2e|",a);//按标准形式的科学计数法输出

    return 0;

}

计算-21+67*2-16/4+8

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int str2int(const char * str){

    int ret =0;

    char ch = 0;

    int stack[10000] = {0};

    int * sp = stack;

    sscanf(str,"%d",sp);

    sp++;

    char buf[100] = {0};

    sprintf(buf,"%d",*stack);

    const char * p = str + strlen(buf);

    while((ch = *p)!='\0'){

        int value = 0;

        for(p++;*p>='0'&& *p<='9';p++){

            value = value * 10 + (*p - '0');

        }

        if(ch == '+'){

            *sp++ = value;

        }else if(ch == '-'){

            *sp++ = -value;

        }else if(ch == '*'){

            *(sp-1) *= value;

        }else if(ch == '/'){

            *(sp-1) /= value;

        }

    }

    for(--sp;sp>=stack;sp--){

        ret += *sp;

    }



    return ret;

}

int main(){

    char str[100] = "-21+67*2-16/4+8";

    int ret = str2int(str);

    printf("%d",ret);//117

}

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值