跟我学C语言(第八天)

第八天(坚持就是胜利)

指针和二维数组关系
int a[2][3]; <==> int (a[2])[3] ==> int (*)[3];


int (*)[3] p; //符合c的变量定义语法,不符合编译器的要求 
    ||
    \/
int (*p)[3];


因为是行序优先,所以我们可以将每行看成一个元素。
xxx a[2] = {a[0],a[1]};

xxx是12个字节的类型(本质是包含了3个int的一维数组)


a 指向了 a[0]元素  a + 1指向了a[1]元素
所以 a + 1跳过了一行
a + i 指向 a[i] *(a + i)操作a[i]数据,a[i]是每行数据的首地址 
a[i] + j每次跳过一个具体元素


行指针
a + i  
&*(a + i) <==> &a[i]

列指针
a[i] + j
*(a + i) + j

指针和指针数组关系
char *str[3] = {"abc","easd","unsi"};
char * *p = str;


int (*str[2])[3];
int (*)[3] str[2];
int (*)[3]*p;
int (**p)[3] = str;


函数:
什么是函数?将一系列的语句封装之后的一个集合。
为什么使用函数?理论上没有函数可以,但是会增加很大的工作量。
   实际上使用函数为了减少工作量(使程序模块化)

函数的基本特性:
函数声明:照着函数定义的原型抄,同时去掉参数名称留下参数类型。


函数定义:返回值 函数名(形式参数);
返回值可以有也可以没有,如果没有用void代替
形式参数可以有可以没有,如果不存在使用void代替(或者什么都不用写),如果有形参(包含数据类型 变量名)
注意:多个参数之间使用逗号分隔


函数调用:
引用方法:
1、没有返回值:函数名(实参);
2、有返回值:变量 = 函数名(实参);


注意:1、一般情况,函数声明出现在函数调用的前面,函数的定义出现在函数的调用后面。
2、很多时候也可以将函数声明和函数定义放在一起使用,这时函数定义一定要出现在函数调用的前面


什么是实参,什么是形参?
实参专门给函数调用使用的,可以是变量可以是常量
形参出现在函数的定义中,必须是变量


实参和形参之间是什么关系?所谓的函数传参
传参的本质就是一个赋值语句。


赋值运算符左端必须是变量(作为形参),右端可以是变量可以是常量(实参)。


函数传参的方式:
针对于基本类型的:
1、复制传参 将原有数据做了一个备份,在函数调用中使用的是备份的值
2、地址传参 将原有数据的地址做了一个备份。
针对于构造类型的:
1、复制传参
2、地址传参
数组的复制传参和地址传参本质都是传递地址,只是格式不同


了解:指针函数(所有资料上提到的指针函数都是胡扯)
就是一个函数,返回值是一个地址。


int fun(int a)
{
操作
return a;
}


char *fun1(char *p)
{
return 指针;
}


main()
{
int x;

x = fun(10);

char a;
char *q;
q = fun1(&a);
}


非常重要:函数指针
函数名:函数名在内存中代表了函数空间的入口地址(地址常量)。
函数空间不连续,数组空间连续。


可以使用某种指针来存放函数名,这种指针就叫做函数指针变量。


如何定义函数指针?看起来好像很难,其实有一条规则:在函数的声明中,将函数名转变为(*),其他位置不变。


函数声明:int test(int,char);
函数指针:int (*)(int,char);这就是一个函数指针类型。
定义指针变量:int (*)(int,char) p;//这种格式编译器不识别,真正用法:int (*p)(int,char);

例如:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
int (*p)(pthread_t *,const pthread_attr_t *,void *(*start_routine) (void *),void *);
p = pthread_create;


void (*fun(int,void (*)(int)))(int);<==> void (*)(int) fun(int,void (*)(int));
fun是一个函数原型,有两个参数,第一个参数是int,第二个参数是void (*)(int).返回值是void (*)(int)


函数递归:一个函数调用其本身


内联函数


作业:
1、在终端输出字符串,然后封装一个函数,这个函数的功能是:去掉输入的字符串中的空格
gets(str); //在终端输入a b c    d e
输出结果为abcde

2、在终端输入一个字符串,假设为:"hello world china"
   输出结果是:china world hello
   提示:使用两次逆序操作。
anihc dlrow olleh
再以空格为分隔符分别逆序单词
















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值