1. 为什么需要函数?

函数就是功能的封装。

函数就是为了实现某个功能而编写的一段代码

scanf()    ,  printf()

2.函数优点:

代码更简洁

代码复用

如果业务逻辑变化,只把相应的函数修改一下就可以

3. 怎么定义一个函数

void start () {

….

}

函数名就是函数在代码段中的入口地址

4. 函数调用

通过函数名调用一个函数,程序执行到这儿后,就会跳转到函数的内部去执行

5. 函数的分类:库函数和自定义函数

6. 函数参数,

在定义函数时声明的参数为形参,在调用函数时的参数为实参。

实参和形参是两个独立的变量,在函数中对形参所做的修改不影响实参。

7.在函数中,可以通过return语句结束函数的执行,也可以通过return语句返回一个值

8.函数的递归调用,

在函数内部又调用函数它本身

指针

int a, b, c;

scanf(“%d%d%d”, &a, &b, &c);

printf(“a=%d, b=%d, c=%d\n”, a, b, c);

printf(“&a = %p, &b=%p, &c=%p\n”, &a, &b, &c);

0x33332222 是一个地址

通过变量名访问该存储空间

定义变量后,可能是编译器,也可能是操作系统,会把变量名和地址的对应关系保存到内存分配表中

内存的每个字节单元都有一个数字编号,称为地址

占8个字节

内存分配表

int * p = &a;

保存地址的变量称为指针变量, p就是一个指针变量,它指向a变量, int * 是数据类型

p = &b;

printf(“%ld, %ld, %ld\n” , sizeof(p), sizeof(int *) , sizeof(*p));

scanf(“%d”, a);  //error, 需要指定数据类型int *, 而不是int

printf(“%lu”, pa) ; //pa变量中的内容按10进制输出

printf(“%p”, pa) ; //pa变量中的内容按地址(十六进制)输出

int *pa = &a;

char *pc = &c;

?? pa多少字节, pc多少字节

MAC ,iphone 5S后是64位,地址占8字节, iPhone 5s之前的手机是32位的,地址占4个字节

所以指针变量保存的就是地址,其大小与地址一样大,占8字节或4字节

二、 *p 是什么

int a = 10;

int *pa = &a;

// &a, &取地址操作,表示到a的地址, pa指向a变量

// *pa, *取值操作,找到pa所标记的地址单元进行取值

// *&a == a

*pa = 20;

printf(“%d\n”, *pa);

printf(“%d\n”, a);

练习:声明整型变量a,存储数字5,定义一个指针变量指向a,通过指针变量修改a变量的值。

三、为什么使用指针?

两个数的交换swap()函数

void swap( int x , int y) {

int t = x;

x = y;

y = t;

}

swap(a, b);

//在swap函数中交换了x和y, 并不影响实参a和b,是形参和实参是两个独立的变量。

指针就是为了访问不在当前栈(堆)里的数据

void swap2( int *p , int *q) { //p = &a, q = &b

int t = *p; // *p == a

*p = *q; // *q == b

*q = t;

}

swap( &a, &b);

需要注意的是,这儿并没有修改形参, 形参是p和q ,而不是*p和*q,对形参p和q的修改并不影响实参

作业:编写函数,交换两个变量的值

编写函数,求三个变量的最大值,在函数中将变量的值清0

编写函数,修改变量的值,将变量的值改为原来值的三次方

scanf(“%d”, &a);  实际上就是在scanf函数中修改变量a的值,所以要用指针,传递一个地址

四、指针与数组

1. 指针加1

int a = 10;

int *p = &a;

printf(“%p\n”, p);

printf(“%p\n”, p+1 ); //指针加1,相当于在原来地址的基础上加一个(int )的长度,或者说加一个(*p)的长度

例:

int a = 10, b = 20;

int *pb = &b;

printf("%d\n", *pb); //20

printf("%d\n", *(pb +1)); //10

2. 指针与数组

int arr[5] = {1 ,2 ,3, 4, 5 };

int *p = &arr[0]; //p指向第0个元素

printf(“%d\n”, *(p+1));

//输出2, p+1表示指向下一个数组元素, *(p+1) 就相当于arr[1]

数组名就是数组的首地址,即 arr == &arr[0],访问数组的某个元素arr[3]时,就是通过数组的首地址的基础上,进行加3访问这个元素

int arr2[5] = {1,2,3,4,5};

int *p = a;

p+1 指向arr2[1]这个元素, *(p+1)就是arr2[1]

a+2指向arr2[2]这个元素, *(a+2)就是arr2[2]

同样

arr2[3]是索引值3的元素

p[3] == arr2[3];  //是等价的

需要注意的是:

p++; //正确,相当于p = p+1

a++; //错误,因为a数组名不能修改

3. 数组参数

数组参数本质上就是一个指针

如:编写一个函数打印数组的各元素

void printArr( int *p ,int  length) {

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

printf(“%d\t”, p[i] ) ;

}

printf(“\n”);

p[2] = 110; //在这儿修改会影响到主调函数的数组

}

int arr[5] = {32,54,55,65,76};

printArr( arr, 5 );

printArr( &arr[0], 5);

printArr( &arr[2], 3);

练习:编写函数,将任意长整型数组逆序列。

五.泛型指针和空指针

1.泛型指针

void *p; //可以指向任何变量,即可以存储任何变量的地址;

int a;

char c;

int *pa = &a;

char *pc = &c;

p = pa;

p = pc;

需要注意的是,泛型指针不能取*操作,不能加减操作

2.空指针:

如果一个指针不初始化,指针可能指向不可预知的地址单元,这种指针称为野指针。如果使用野指针,可能会产生不可预知的错误

int *p;

*p = 123; //危险

为了防止野 指针,如果创建指针时没有明确的指向,需要将指针设置为空指针

int * p = NULL;

六 const关键字

const修饰变量a,则变量a不能被修改

const int a = 5;

a++; //error, a不能被修改

const修饰指针变量

const int *p = &a;

int const *q = &a;

q或者q可以指向其他的变量,但是,*p和*q是常量,不能被修改,即:

*p = 30; 错误

*(p+1) = 23; //也不对, *p是一个const int常量,则*(p+1)也是一个const int常量

可以进行强制类型转换如下:

*(((int *) p) + 1) = 34;

int * const p = &a;   表示指针变量p是一个常量,不能修改p,即

p = &b; //错误,

*p = 444; //正确

作业:编写函数,求任意长度整形数组的平均数

编写函数,求任意长度整形数组中第二大的数

编写函数,传入一个字符串数组,找出最长的英文单词,返回最长单词的起点索引

编写函数,传入一个字符数组,返回数组中第一个出现的字母,如果没有字母返回0

编写函数,传入一个字符数组,无需要返回值,将数组中字符压缩打印,如传入helloworld,打印h1e1l3o2w1r1d1

编写函数,传入两个浮点数和一个字符(+、-、*、/),返回计算结果,如果除数是0,返回-9999

1. 分析 int a; int * p = &a;

2. 分析 *p

3. 分析 p++;

4. 分析(*p)++;

5. 分析函数传地址。

6. 画图分析函数中改变*p,就是改变本体。

7. 使用指针,写两个相应的函数完成:

int a, b, c;

char d, e, f;

整型求和后,将a,b, c置-1,

d, e, f 中字符,大小写转换。

8. 分析int * p = 5;是可以的;int b = &a;也是可以的;int b = &a;int * p = b也是可以的,到底是怎么个过程。

1.函数实现输入一行字符,另一函数实现分别统计出其中英文字母、空格、数字和其它字符的个数。

2.函数实现输入一个已经排好序的数组。再输入一个数,要求按原来的规律将它插入数组中。

3.函数实现将一个数组逆序。(并非逆序输出,是数组本身逆序)

4.函数实现有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数

5.函数实现输入一行字符,最大长度为90,统计出其中有多少个字符串,不算标点。例如:

输入:Hi, Welcome to Qianfeng!!

输出:4

6.编写一个函数,时分秒,输出该时间的下一秒。如输入23时59分59秒,则输出0时0分0秒(**)

输入格式为    23:59:59

输出格式为    0:0:0

7. 编写函数将一个n*n矩阵转置,例如:(****)

1 2 3 4     1 5 3 4

5 6 7 8 ->  2 6 2 7

3 2 5 9     3 7 5 2

4 7 2 3     4 8 9 3

8.函数实现,字符串排序,以main函数参数形式输入9个字符串,然后将字符串按字母顺序进行排序,如果首个字母相同则再比较下一个字母,以此类推。比如:

"abcdefg", "yusdfsdf", "bsdf", "bjiiig", "zddd",排序后为:

"abcdefg", "bbjiiig", "bsdf", "yusdfsdf", "zddd"。

C语言中的函数与指针的更多相关文章

  1. C语言中 指向函数的指针 简介

    引子:在学习CPrimerPlus的第十四章的14.13节中,遇到了如下三行文字,是有关指向函数的指针的,把我搞晕了. char * fump(); //返回指向char的指针的函数 char (* ...

  2. C语言中的函数指针

    C语言中的函数指针 函数指针的概念:   函数指针是一个指向位于代码段的函数代码的指针. 函数指针的使用: #include<stdio.h> typedef struct (*fun_t ...

  3. 利用C语言中的函数指针实现c++中的虚函数

    C语言中的函数指针 #include<stdio.h> int fun1(int a) { return a*a; } int fun2(int a) { return a*a*a; } ...

  4. C语言中的函数

    C语言中的函数 目录 概述——对函数的理解 C语言中函数的定义和声明 函数允许的参数类型 函数允许的返回类型 递归 概述 由于有些代码段在编写程序的时候经常会用到,此时我们为了减少代码文件的长度和增加 ...

  5. C语言学习笔记--函数与指针

    1. 函数类型 (1)C 语言中的函数有自己特定的类型,这个类型由返回值.参数类型和参数个数共同决定.如 int add(int i,int j)的类型为 int(int,int). (2)C 语言中 ...

  6. C语言中的函数与数学上的函数很类似

    函数,是C语言编程中一个很重要的概念,重要到个人认为可以与指针并驾齐驱.好多教材.老师.学习资源都会专门挑出一章来讲函数.我今天也来说说函数,只不过我是从数学课上的函数来引申到C语言中的函数. 先来说 ...

  7. 想精度高,可以考虑用c语言中的函数gettimeofday

    大家好: 在 win32 + bcb 时, 有个 GetTickCount() 返回第统启动到现在的 tick, 单位 ms.请问在 Linux + qt5 怎样实现呢? 如果用 QDateTime ...

  8. js课程 3-10 js中字符串函数数组函数和其它语言中对应函数的区别和联系是什么

    js课程 3-10  js中字符串函数数组函数和其它语言中对应函数的区别和联系是什么 一.总结 一句话总结:js中是对象点方法的形式,这些方法都是对象的方法,而在php.java中却不是这样. 1.j ...

  9. 策略设计模式与c语言中的函数指针

    在C语言中有一个非常重要的概念-函数指针,其最重要的功能是实现回调函数(指函数先在某处注册,而它将在稍后某个需要的时候被调用)在java语言中没有指针的概念,但是可以利用接口和指针实现类似的功能,具体 ...

随机推荐

  1. 【原创】Kakfa log包源代码分析(一)

    Kafka日志包是提供的是日志管理系统.主要的类是LogManager——该类负责处理所有的日志,并根据topic/partition分发日志.它还负责flush策略以及日志保存策略.Kafka日志本 ...

  2. UEditor 1.4.3.1.NET版本上传配置备忘录

    UEditor用起来还是挺方便的,下面是记录一下在上传中的配置问题(主要是上传图片的配置,其他的都是类似的). 我下载的是UEditor 1.4.3.1 .NET版本. 官网的配置说明地址为 http ...

  3. 【转载】async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  4. .net又一个生成缩略图的方法,不变形

    生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 /// <summary> /// 为图片生成缩略图 by 何问起 /// ...

  5. 用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)

    本文讲述使用Senparc.Weixin框架来快速处理各种接收事件推送.这里的消息指的是传统的微信公众平台消息交互,微信用户向公众号发送消息后,公众号回复消息给微信用户.包括以下类型: 1 subsc ...

  6. 暴风冯鑫:去美国香港的99%都亏,互联网公司打死都要回A股

        “上市之后,我回答得最多的两句话:一句是运气好:另一句是有好运气要好好地使用它.” 5月18日,暴风科技上市55天后,首享科技大厦办公室里,暴风科技CEO冯鑫这样对我说. 在经历了36个涨停之 ...

  7. UML类图画法及其之间关系

    1.泛化又名继承(Generalization),带空心箭头的实线表示,箭头指向父类 2.实现(Realization),带空心的虚线表示 3.关联(Association),类与类之间的关联,它使一 ...

  8. spring3.0结合Redis在项目中的运用

    推荐一个程序员的论坛网站:http://ourcoders.com/home/ 以下内容使用到的技术有:Redis缓存.SpringMVC.Maven.项目中使用了redis缓存,目的是在业务场景中, ...

  9. [javaSE] 反射-获取类的成员属性和构造方法

    成员属性和构造方法皆为对象,通过Class对象的方法可以得到 package com.tsh.reflect; import java.lang.reflect.Constructor; import ...

  10. Discuz X2任务开发

    简单描述 由于公司的需求要在系统中添加任务管理,用户通过完成任务而获得一定的奖励,因此其设计过程需要考虑到: 1.由于任务都是在系统中相关功能块处做一些相关事情,比如说在做题系统中完成指定的试题[1] ...