第十天c语言自学笔记

char data1[5];
char *p1 = data1;    
    
float data2[5];
float *p2 = data2;

char data4[4][5];
char (*p4)[5] = data4;
    
char *data5[5];
char* *p5 = data5;

char (*data6[5])[6];
char (*(*p6))[6]= data6;

一、函数名的本意
1、函数名的本质
数组名、函数名==常量的地址,连续空间的首地址
函数名无法按照字节方式访问,CPU的PC决定访问方式(函数方式访问)

int  (*p)(const char *,...) = printf;//...不定参数,压栈
printf("%p\n",printf);
printf("%p\n",p);
p("hello\n");


要求设置一绝对地址为0x67a9的整形变量的值为0xaa66
 int *p = (int *)0x67a9;
*p = 0xaa66;


设计一个代码,让CPU到0x20008000的位置上执行
(void  (*)(void) )0x20008000
( (void  (*)(void) )0x20008000 )()

void (*fun)(void) = (void  (*)(void) )0x20008000;
fun()

typedef  void  (*handler)(void)//(handler是一个输入参数void返回值为void的)地址的变量
typedef  void  (*handler)(void)//(handler是一个输入参数void返回值为void的)地址的别名

handler fun  =  (handler)0x20008000
fun()

int  (*p)(const char *) = (int  (*)(const char *) )printf

typedef  int  (*show_t)(const char *,...)
show_t myshow = (show_t)printf;
myshow("hello\n");

2、函数形参执行顺序
形参:实现功能者为了接收调用者传来的信息,临时分配一段区域来接收
实参:调用者分配处的空间

3、函数的承上启下
 承上启下 :获取信息  反馈信息


二、函数接收信息方式
函数思想:模块化设计的思想--模块如何组合在一起

如果设计子模块,是的其他模块可以方便组合 
子模块需要接收上层模块发出的地址才能对发出的地址进行操作
fop(a);
fop(&a);


三、子模块修改地址变量的方法
上层空间,需要子模块来修改
1、调用者  必须把这个空间的首地址传递过去
2、子模块设计者  必须通过这个地址反向查找进行更新

函数传递了地址:
1、子模块具有了修改上层空间的能力
2、子模块可以连续访问首地址的内容(看/改)
a、看连续的空间  void  fun(const  int *p,int  len)
b、看一个数据类型  void  fun (int  p)
c、改连续空间  void  fun  (int *p,int len)
d、改一个数据类型 void  fun (int *p)

统计字符空间中空格的个数
int  cntSpace(const  char  *str){}

删除字符空间中空格的个数
void  cntSpace( char  *str){}
字符空间已更改,是否返回根据实际需求

strcpy有返回值,方便与链式调用,这个函数的返回值是另外一个函数的输入参数
strlen( strcpy( buf,"hello" ) )

四、任务查找框架
代码--数据  分离思想  耦合度降低
维护操作符与函数名相对应的一张表
操作符   函数名
+        my_add()
-         my_sub()
*         my_mul()
/         my_div()
类似于一个结构体

struct  data_tab{
    char  op;
    int  (*handler)(int ,int)
};

struct  data_tab  table[4] = {};

#include<stdio.h>

int conver(char *str){
    int res = 0;
    int n = 0;
    
    while( *str ){
        if( !( (*str >= '0') && (*str <= '9') ) ){
            break;
        }
        n = *str - '0';
        res = res * 10 + n;
        str ++;
    }
     
    return res;
}

int my_add(int n1,int n2){
    return n1+n2;
}

int my_sub(int n1,int n2){
    return n1-n2;
}

int my_mul(int n1,int n2){
    return n1*n2;
}

int my_div(int n1,int n2){
    return n1/n2;
}

//定义一个操作符和操作函数的表格 
typedef struct {
    char op;
    int  (*handler)(int ,int); 
}My_Tab;

My_Tab data[] = {
    { '+',my_add },
    { '-',my_sub },
    { '*',my_mul },
    { '/',my_div },
};

int main(int argc,char *argv[]){
    int num1 = 0;
    int num2 = 0;
    int result = 0;
    int i = 0;
    
//    if( argc != 4 ){
    if( argc > 4 ){
        printf("Usage:输入个数多了\n");
        return -1;
    }
    else if( argc < 4){
        printf("Usage:输入个数少了\n");
        return -1;
    } 
    
    num1 = conver(argv[1]);
    num2 = conver(argv[3]);    
    
    printf("num1 = %d, num2 = %d\n",num1,num2);
    
    for( i = 0; i < sizeof(data)/sizeof(data[0]); i ++){
        if( (data[i].op == argv[2][0]) && (data[i].handler) ){
            result = data[i].handler(num1,num2);
            break;
        }    
    }
    
    if( i == sizeof(data)/sizeof(data[0]) ){
        printf("输入错误\n");
        return -1;
    }else{
        printf("%d\n",result);
    }
    
    return 0;
}


五、stroul的使用
头文件:#include<stdlib.h>
atoi--只能进行转换,不能查找错误
strtol--能通过返回指针来确定是否转换错误

int  main(){
    const  char  *p = "123abc";//const  char  *p = "123";
    char  *x;
    int  res  = strtol(p, &x,10);
    printf("%p,%x",x,x[0]);
    printf("res = %d\n",res);
    return 0;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值