结构体访问成员变量
假设有一个结构体 struct Point 和一个指向 Point 的指针:
struct Point {
int x;
int y;
};
struct Point p = {10, 20};
struct Point *p_ptr = &p;
可以通过 -> 运算符访问结构体 p 的成员 x 和 y,如下
int x_val = p_ptr->x; // 等同于 (*p_ptr).x
int y_val = p_ptr->y;
为什么使用 ->
简便性:-> 是 (p_ptr).x 的简写,避免了使用 和 () 的繁琐语法。
指针访问:-> 直接表示对结构体指针成员的访问,方便理解。
Typedef:定义新类型
C allows us to define new data type (names) via typedef:
typedef ExistingDataType NewTypeName;
Examples:
typedef float Temperature;
typedef int Matrix[20][20];
函数指针
我的理解,就是 typedef 定义一个名字,声明 参数、返回值 是些啥。然后这个名字,当作类型声明,快速复制其他名字的函数。
注意,赋值给其他新函数名字的时候,后面的函数名字加不加&都可以,因为C会实际将其处理为函数地址。
// Define a function pointer type, which points to a function
typedef int (*ComparatorFuncPtr)(int, int);
int IsLarger(int a, int b) {
return a > b;
}
ComparatorFuncPtr fptr = &IsLarger;
或如:
typedef int (*ComparatorFuncPtr)(int, int);
int IsLarger(int a, int b) {
return a > b;
}
ComparatorFuncPtr fptr1 = IsLarger; // Implicit pointer
ComparatorFuncPtr fptr2 = &IsLarger; // Explicit pointer
int result1 = fptr1(5, 3); // Calls IsLarger(5, 3)
int result2 = fptr2(5, 3); // Also calls IsLarger(5, 3)
使用场景
1.回调函数 (Callback Functions)
函数指针可以作为参数传递给另一个函数,通常用于回调机制。在某些场景下,比如排序、事件驱动程序或者信号处理,你可以将特定的函数通过函数指针传递给库函数,库函数在合适的时机调用你传递的函数。
示例:使用函数指针作为回调函数
#include <stdio.h>
void callback(int result) {
printf("Callback called with result: %d\n", result);
}
void compute(int a, int b, void (*callbackFunc)(int)) {
int sum = a + b;
callbackFunc(sum); // 调用传入的回调函数
}
int main() {
compute(3, 4, callback); // 传入 callback 函数指针
return 0;
}
在这个例子中,compute函数接收一个函数指针参数 callbackFunc,然后在合适的时候调用这个函数。
2.实现策略模式或动态函数调用
函数指针可以让你在程序运行时选择不同的函数来执行相同的任务。这在实现不同的策略或行为时非常有用,比如不同的排序规则、比较函数、或者动态处理不同类型的数据。
示例:不同的比较函数传递给排序算法
#include <stdio.h>
// 比较函数
int ascending(int a, int b) {
return a - b;
}
int descending(int a, int b) {
return b - a;
}
// 使用函数指针的通用排序函数
void sort(int* arr, int size, int (*compare)(int, int)) {
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (compare(arr[i], arr[j]) > 0) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
int main() {
int arr[] = {5, 2, 9, 1, 5, 6};
int size = sizeof(arr) / sizeof(arr[0]);
sort(arr, size, ascending); // 使用升序比较
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
sort(arr, size, descending); // 使用降序比较
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
传递命令行参数:参数数量 参数值 环境变量值
首先注意啊,argv 和 env都存储的是字符串,如果你输入参数是数字,需要转换成数字才行
参数数量 参数值
argc (Argument Count)
./my_program arg1 arg2 arg3
argc will be 4:
argv[0] is the name of the program (“./my_program”).
argv[1] is "arg1".
argv[2] is "arg2".
argv[3] is "arg3".
argv (Argument Vector)
char argv or char argv[]*
这是个存储 char 的数组,char 是字符指针,指向不同字符串的首地址(第一个字符的地址)
比如我们传参,
./exe aaa bbb
程序中,
Char a[]=“aaa”
Char b[]=“bbb”
Char c[]=“ccc”
a,b,c名字本身就是char,或者说,*首地址
char a = “hello”; char b = “world”; char *c = “example”;
argv 是一个指针数组,也就是存储多个 char* 的数组。每个元素都是一个字符指针,指向一个字符串。
具体来说,argv 的类型是 char*,表示它是“字符指针的指针”。换句话说,它是一个数组,其中的每个元素都是 char,这些 char* 指向的是具体的字符串(即字符数组)。
argv[0] is the name of the program (or the path used to execute it).
argv[1] to argv[argc-1] are the actual arguments passed to the program.
int main(int argc, char **argv, char **env){
Print(“argc = %d\n”, argc);
Print(“argv[0] = %d\n”, argv[0]);
Print(“argv[1] = %d\n”, argv[1]);
For (int I=0; i<argc; i++){
Xxx
}
}
环境变量值
char *env 或 char env[]
形式同char **agv,env是编译器默认定义好的数组
这些字符串是环境变量的名称和值,通常以 “NAME=VALUE”
#include <stdio.h>
int main(int argc, char **argv, char **env) {
// 遍历并打印所有环境变量
for (int i = 0; env[i] != NULL; i++) {
printf("%s\n", env[i]);
}
return 0;
}
Welcome to point out the mistakes and faults!
Gitalking ...