函数链式访问:
一.strlen()
int main() {
int len = strlen("anocineoc");
printf("%d\n", len);
//链式访问
printf("%d\n", strlen("anocineoc"));
return 0;
}
二.printf()
printf("%d", printf("%d", printf("%d", 43)));
printf返回值是int类型
返回的值是里面元素的个数
函数先声明再调用
//先声明函数
int Add(int x, int y);
//
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("sum = %d\n", sum);
return 0;
}
//函数的定义
int Add(int x, int y)
{
return x + y;
}
注意:
int Add(int x, int y);
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("sum = %d\n", sum);
return 0;
}
ctrl+F7(编译)不会出错,因为没有链接过程
ctrl+F5(编译+链接)会报错,因为链接会去找这个函数存在不存在,不存在所以报错
在项目里写函数应该写到头文件中
引头文件,相当于把头文件中的函数声明全部拷贝过来
add.h
int Add(int x, int y);
add.c
#include "add.h"
int Add(int x, int y) {
return x + y;
}
test.c
#include "add.h"
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("sum = %d\n", sum);
return 0;
}
四.开源项目但不想让别人知道函数细节
把自己写的函数的.c和.h文件单独存放在一个项目中,然后如下图生成.lib文件,ctrl+F5生成.lb文件。就可以把.lib文件和.h文件(函数声明)开源给别人。
把.lib和.h文件放在和源文件(即.c文件的目录)的目录下
#include "add.h"
//导入静态库
#pragma comment(lib, "add.lib")
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("sum = %d\n", sum);
return 0;
}
即可正常运行
递归
一.最简单的递归
int main() {
printf("hehe\n");
main();
return 0;
}
每一次函数调用都要在栈区上开辟一块空间。
二.输入一个整数,按顺序打印它的每一位。输入1234,输出1 2 3 4.
void print(int n)//
{
if (n > 9)
{
print(n / 10);//
}
printf("%d ", n % 10);
}
int main()
{
int num = 0;
scanf("%d", &num);//1234
//打印num的每一位
//1 2 3 4
print(num);//print函数就可以把num的每一位打印在屏幕上
//
//要想打印print(1234)
//先打印print(123) 再打印4
//先打印print(12) 再打印3 4
//先打印print(1) 再打印2 3 4
//1 2 3 4
//
return 0;
}
三.编写函数不允许创建临时变量,求字符串长度
//计数器的方式1
int my_strlen1(char* str)
{
int count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
//my_strlen("abcdef")
//1+my_strlen("bcdef")
//1+1+my_strlen("cdef")
//1+1+1+my_strlen("def")
//1+1+1+1+my_strlen("ef")
//1+1+1+1+1+my_strlen("f")
//1+1+1+1+1+1+my_strlen("")
//1+1+1+1+1+1+0
//6
//递归的方式
int my_strlen2(char* str)
{
if (*str != '\0')
return 1 + my_strlen2(str + 1);
else
return 0;
}
int main()
{
char arr[] = "abc";
//数组名是首元素的地址 - char*
int len = my_strlen2(arr);
printf("%d\n", len);
return 0;
}
四.求n的阶乘
int Fac(int n)
{
if (n <= 1)
return 1;
else
return n*Fac(n - 1);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fac(n);
printf("%d\n", ret);
return 0;
}
五.求第n个斐波那契数
1 1 2 3 5 8 13 21 34 55
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
效率非常低,当输入为50时,就已经比较难计算了
注:
计算一下n==3出现的次数
int count = 0;
int Fib(int n)
{
if (n == 3) {
count++;
}
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", count);
return 0;
}
可见递归效率非常低
计算第n个斐波那契的另一种方法:
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n>2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d\n", ret);
return 0;
}
数组
int main()
{
int n = 10;
int arr[n];//变长数组-C99标准中引入的。VS2013对C99的支持不好。
return 0;
}
会报错
一.初始化
未初始化:
int main() {
int arr[10];
return 0;
}
所以创建数组后一定要初始化。
初始化的各种情况:
int main()
{
//初始化
int arr[10] = {1};//不完全初始化
int arr2[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr3[10] = {0};
int arr4[] = { 0 };//
char ch[10] = { 0 };
char ch2[10] = {'1', 'b', 'c'};
char ch3[] = "abc";
return 0;
}
因为没说是几个元素,所以自动根据{ }里来创建几个元素
这个没有’\0’
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a', 'b', 'c'};
//因为后面没有'\0'所以会一直打印
char arr3[] = { 'a', 'b', 'c', 0 };
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
printf("%d\n", strlen(arr3));
return 0;
}
注字符数组及其定义和初始化,C语言字符数组详解 (biancheng.net)
C语言中 在什么情况下声明数组时可以不指出数组长度?
带有初始化器的定义,此时数组大小可由初始化器长度推出:int a[] = {1};
或 char a[] = "a";
;
二.数组在内存中的情况
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;//数组名-数组首元素的地址
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p <=======> %p\n", i, &arr[i], p+i);
//p+i -- 是数组arr中下标为i的元素的地址
}
return 0;
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;//数组名-数组首元素的地址
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
for ( i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//使用指针p,来访问了数组
}
return 0;
}