函数
函数要有 功能、参数、返回值
格式:
数据类型 函数名(形参列表)
{
代码段;
return 变量名或常量或表达式;
}
注意return的返回值类型要和定义函数时的数据类型保持一致;
不需要返回值时,数据类型可以用void表示
声明:
数据类型 函数名();
定义的函数可以直接写在主函数上边,也可写在下边,注意:写在下边时,要提前声明
(怎么提前声明)
#include <stdio.h>
int fun(int a, int b); /*这就是提前声明*/
int main
{
int a = 0, b = 0;
fun(a,b);
return 0;
}
int fun(int a, int b)
{
//代码段
}
格式:
- 不需要参数,也不需要返回值
函数调用:函数名();
#include<stdio.h>
void hq()
{
printf("hqyjyyds\n");
printf("123456\n");
}
int main(int argc, char const *argv[])
{
printf("aaaa\n");
hq();
return 0;
}
- 需要参数,不需要返回值
函数调用:函数名(实参列表);
#include<stdio.h>
void hq(int a,int b)
{
int sum=a+b;
printf("%d\n",sum);
}
int main(int argc, char const *argv[])
{
hq(5,8);
return 0;
}
- 不需要参数,需要返回值
#include<stdio.h>
int hq()
{
int sum=5+8;
printf("%d\n",sum);
return sum;
}
int main(int argc, char const *argv[])
{
int res=hq();
printf("%d\n",res);
return 0;
}
- 需要参数,需要返回值
#include<stdio.h>
int hq(int a,int b)
{
int sum=a+b;
printf("1:%d\n",sum);
return sum;
}
int main(int argc, char const *argv[])
{
int res=hq(5,6);
printf("**%d\n",res);
printf("+++%d\n",hq(8,9));
return 0;
}
形参:函数定义时,定义的形参变量,是形式上存在的参数,只有在调用函数时才开辟内存空间。
实参:调用函数时,实际传递的值。
练习:写一个函数,求字符串中某个字符出现的次数(例如:hello的l出现了2次)
#include <stdio.h>
//写一个函数,求字符串中某个字符出现的次数
int count(char *p,char x)
{
int no = 0;
while(*p)
{
if (*p == x)
{
no++;
}
p++;
}
return no;
}
int main()
{
char s[50];
char x;
printf("输入一串字符串:");
scanf("%s",s);
getchar(); //回收垃圾字符“回车”
printf("要查询哪个字符的出现次数?:");
scanf("%c",&x);
int res = count(s,x);
printf("%d\n",res);
return 0;
}
练习:计算字符串中某个字符首次出现的位置下标
//计算字符串中某个字符首次出现的位置下标
#include <stdio.h>
int xb(char *p, char x)
{
int location = 1;
while(*p != x)
{
p++;
location++;
}
return location;
}
int main(int argc, char const *argv[])
{
char s[50];
char x;
printf("输入一串字符串:");
scanf("%s",s);
getchar();
printf("想要查询的字符:");
scanf("%c",&x);
int res = xb(s,x);
printf("首次出现在第%d个位置\n",res);
return 0;
}
编写函数实现strlen的功能
#include <stdio.h>
//编写函数实现strlen的功能
int strl(char *p)
{
int count = 0;
while(*p)
{
p++;
count++;
}
return count;
}
int main(int argc, char const *argv[])
{
char s[50];
scanf("%s",s);
int res = strl(s);
printf("%d\n",res);
return 0;
}
函数传参
值传递
单向传递,把实参传递给形参使用,改变形参实参不受影响
(把值复制一份,进行修改,不影响原来的内容)
输出后a和b的值不变
地址传递
双向传递 修改形参,实参会一起改变
(把变量的地址传递过去,然后通过地址间接修改原内容)
#include <stdio.h>
//地址传递
void fun(int *c, int *d)
{
(*c)++;
*d += 3;
}
int main(int argc, char const *argv[])
{
int a = 5, b = 3;
fun(&a, &b);
printf("%d %d\n", a, b);
return 0;
}
a和b的值会改变
练习:封装函数实现两个变量值的交换
//封装函数实现两个变量值的交换
#include <stdio.h>
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, char const *argv[])
{
int a = 0;
int b = 0;
printf("输入两个值:");
scanf("%d %d", &a, &b);
swap(&a, &b);
printf("交换:%d %d", a, b);
return 0;
}
数组传递
#include <stdio.h>
//数组传递
char *fun(char *p)
{
p = "hello";
return p;
}
int main(int argc, char const *argv[])
{
char *q = fun("abc");
printf("%s\n",q);
return 0;
}
开辟堆区空间
malloc()函数 和 free()函数
#include <stdlib.h>
void *malloc(size_t size);
功能:开辟堆区空间
参数:开辟堆区空间的大小
返回值:无
成功:开辟堆区空间的首地址
失败:NULL
void free(void *ptr);
功能:释放堆区空间
参数:要释放的堆区空间首地址
返回值:无
思考
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void fun(char *p)
{
p = (char *)malloc(32);
strcpy(p, "hello"); //字符串复制函数,将字符串"hello"复制到指针p
}
int main()
{
char *m = NULL;
fun(m);
printf("%s\n", m);
}
不会成功打印hello,为什么?