其中a, b 叫形参,num1, num2 叫实参。 Tip:形参和实参的个数不同,笔者编译器报错如下(一个说给函数的参数少,一个说给函数的参数多了):
// 3个形参,2个实参
int add(int a, int b, int c) {}
// error: too few arguments to function call, expected 3, have 2
int result = add(num1, num2);
复制代码
// 2个形参,3个实参
int add(int a, int b) {}
// error: too many arguments to function call, expected 2, have 3
int result = add(num1, num2, num1);
复制代码
函数调用过程
函数调用过程:
通过函数名找到函数的入口地址
给形参分配内存空间
传参。包含值传递和地址传递(比如js中的对象)
执行函数体
返回数据
释放空间。例如栈空间
请看示例:
#include <stdio.h>
// 2. 给形参分配内存空间
// 3. 传参:值传递和地址传递(比如js中的对象)
// 4. 执行函数体
// 5. 返回数据
// 6. 释放空间。例如栈空间:局部变量 a,b,sum
int add(int a, int b) {
int sum = a + b;
return sum;
}
int main() {
int num1 = 3;
int num2 = 5;
// 1. 通过函数名找到函数的入口地址
int result = add(num1, num2);
printf("add() 的地址:%p\n", add);
printf("%d\n", result);
return 0;
}
复制代码
输出:
add() 的地址:0x401130
8
复制代码
练习-sizeof
题目:以下两次 sizeof 输出的值相同吗?
#include <stdio.h>
void printSize(int arr[]) {
printf("Size of arr: %zu\n", sizeof(arr));
}
int main() {
int nums[] = {1, 2, 3, 4, 5};
printf("Size of nums: %zu\n", sizeof(nums));
printSize(nums);
return 0;
}
复制代码
运行:
开始运行...
// sizeof(arr) 获取的是指针类型 int * 的大小(在此例中是8字节)
/workspace/CProject-test/main.c:4:40: warning: sizeof on array function parameter will return size of 'int *' instead of 'int[]' [-Wsizeof-array-argument]
printf("Size of arr: %zu\n", sizeof(arr));
^
/workspace/CProject-test/main.c:3:20: note: declared here
比如 apple 和 applea比较,第一次是 a 等于 a,继续比较,直到第六次 \0 和 a 比较,\0 的 ASCII 是0,而a 是97(可打印字符的ASCII值通常位于32-126之间),所以 applea 更大
大小写敏感。例如 A 的 ASCII 是 65。
例如:比较字符串 str1 和字符串 str2 的大小
如果 str1 小于 str2,则返回一个负整数(通常是 -1)。
如果 str1 大于 str2,则返回一个正整数(通常是 1)。
如果 str1 等于 str2,则返回 0。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "applea";
int result = strcmp(str1, str2);
if (result < 0) {
printf("str1 is less than str2\n");
} else if (result > 0) {
printf("str1 is greater than str2\n");
} else {
printf("str1 is equal to str2\n");
}
return 0;
}
复制代码
输出:str1 is less than str2
strncmp()
strncmp - 比较两个字符串的前n个字符是否相等
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "applea";
// int result = strcmp(str1, str2);
int result = strncmp(str1, str2, strlen(str1));
if (result < 0) {
printf("str1 is less than str2\n");
} else if (result > 0) {
printf("str1 is greater than str2\n");
} else {
printf("str1 is equal to str2\n");
}
return 0;
}
复制代码
输出:str1 is equal to str2
strchr()
strchr - 在一个字符串中查找指定字符第一次出现的位置。语法:
// str是要搜索的字符串;
// c是要查找的字符。
char* strchr(const char* str, int c);
复制代码
函数返回值:
如果找到指定字符,则返回该字符在字符串中的地址(指针)。
如果未找到指定字符,则返回NULL。
Tip:可以通过地址相减返回字符在字符串中出现的索引值。请看示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, world!";
char* result = strchr(str, 'o');
if (result != NULL) {
// 返回字符'o'的位置,并输出字符 'o' 到结尾的字符串
printf("找到了字符'o',位置为:%s\n", result);
// 地址相减,返回字符第一次出现的索引
printf("找到了字符'o',位置为:%ld\n", result - str);
}
else {
printf("未找到字符'o'\n");
}
return 0;
}
复制代码
输出:
开始运行...
找到了字符'o',位置为:o, world!
找到了字符'o',位置为:4
运行结束。
复制代码
strrchr
strrchr - 相对strchr()逆序查找。
修改上述示例(strchr)一行代码:
- char* result = strchr(str, 'o');
+ char* result = strrchr(str, 'o');
复制代码
运行:
开始运行...
找到了字符'o',位置为:orld!
找到了字符'o',位置为:8
运行结束。
复制代码
strstr
strstr - 用于在一个字符串中查找指定子字符串的第一次出现位置。语法:
char* strstr(const char* str1, const char* str2);
复制代码
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello, World!";
char *subStr = "World";
char *result = strstr(str, subStr);
if (result != NULL) {
printf("找到子字符串:%s\n", result);
} else {
printf("未找到子字符串。\n");
}
return 0;
}
复制代码
关键字
C 语言有如下关键字:
关键字描述关键字描述auto声明自动变量enum声明枚举类型break跳出当前循环或开关语句extern声明外部变量或函数case开关语句分支标签float声明单精度浮点型变量或函数返回值类型char声明字符型变量或函数返回值类型for循环语句const声明只读变量goto无条件跳转语句continue结束当前循环的迭代,并开始下一次迭代if条件语句default开关语句的默认分支int声明整型变量或函数返回值类型do循环语句的循环体long声明长整型变量或函数返回值类型double声明双精度浮点型变量或函数返回值类型register声明寄存器变量else条件语句中否定条件的执行体return从函数返回值short声明短整型变量或函数返回值类型signed声明有符号数类型sizeof获取某个数据类型或变量的大小static声明静态变量struct声明结构体类型switch开关语句typedef声明类型别名union声明联合体类型unsigned声明无符号数类型void声明无类型volatile说明变量可以被意外修改,应立即从内存中读取或写入而不进行优化while循环语句重点说一下:static、const(已讲过)、extern。
auto
在C语言中,auto 关键字并不是必需的,因为所有在函数内部声明的变量默认都是自动变量。所以在实际编码中,很少使用 auto 关键字进行变量声明
#include <stdio.h>
int main() {
auto int x = 10; // 等于 int x = 10;
printf("The value of x is: %d\n", x); // 输出:The value of x is: 10