int main() {
int arr1[10] = {0};
int(*p1)[10] = &arr1;// p1存放的是数组的地址,该数组有10个int空间
int* arr2[10] = {nullptr}; // p2存放的是int指针
for (int i = 0; i < 10; i++) {
(*p1)[i] = i * 10;
}
for (int num : (*p1)) {
printf("%d\n", num);
}
int* (*p2)[10] = &arr2; // p2存放的是数组的地址,数组存放的是10个int指针
return 0;
}
int add_int(int a, int b) {
return a + b;
}
int sub_int(int a, int b) {
return a - b;
}
int main() {
int a = 10;
int b = 20;
int c = 0;
int (*p_fun)(int, int) = nullptr;//指向函数的指针,同参数,同返回值即可指向
p_fun = &add_int; //同p_fun = &add_int;
c = (*p_fun)(a, b); //旧的调用方法
c = p_fun(a, b); // 新的调用方法,不直观
p_fun = &sub_int;//同p_fun = sub_int;
return 0;
}
int main() {
int a = 10;
int b = 20;
int c = 0;
int (*p_fun)(int, int) = nullptr;
p_fun = &add_int;
//p_arr1是数组,数组有两个元素,每个元素都是指针,每个指针存放一个函数的地址
int (*p_arr1[2])(int, int) = { &add_int, &sub_int };
// p_arr1[0] = p_fun;
for (int i = 0; i < 2; i++) {
c = (*p_arr1[i])(a, b);//p_arr1[i](a, b)
printf("%d\n", c);
}
//p_arr2是数组,数组有两个元素,每个元素都是指针,每个指针存放一个函数的地址
int* (*p_arr2[2])(int, int);
return 0;
}
函数指针和基本数据类型指针的区别
int main() {
int a = 10;
int b = 20;
int c = 0;
int (*p_fun)(int, int) = nullptr;
//p_arr1是数组,数组有两个元素,每个元素都是指针,每个指针存放一个函数的地址
int (*p_arr1[2])(int, int) = { &add_int, &sub_int };
p_fun = p_arr1[0];
sizeof(p_fun);//4
sizeof(*p_fun);//无法计算
p_fun++; // 函数指针不可自增,因为函数大小无法计算,不能通过计算指向下一个函数
return 0;
}
回调函数调用方式
void test1(int a, int b, int(*p_fun)(int, int)) {
if (p_fun != nullptr) {
int c = (*p_fun)(a, b);
printf("%d\n", c);
}
}
//编译器自动将形参的函数声明转换成函数指针
void test2(int a, int b, int p_fun (int, int)) {
if (p_fun != nullptr) {
int c = (*p_fun)(a, b);
printf("%d\n", c);
}
}
int main() {
int a = 10;
int b = 20;
test1(a, b, &add_int);
test2(a, b, &sub_int);
return 0;
}
利用回调函数打印不同类型数组
struct Student {
char name[16];
int age;
};
void* print_int(void* p) {
// 把指针p强转
const int* tmp = (const int*)p;
printf("%d ", *tmp);
return (void*)(tmp + 1);
}
void* print_double(void* p) {
// 把指针p强转
const double* tmp = (const double*)p;
printf("%f ", *tmp);
return (void*)(tmp + 1);
}
void* print_stu(void* p) {
// 把指针p强转
const struct Student* tmp = (const struct Student*)p;
printf("%s %d\n", tmp->name, tmp->age);
return (void*)(tmp + 1);
}
// 这里用void*是因为不确定参数的类型
void print_arr(void* arr, int len, void* (*p_fun)(void*)) {
void* tmp = arr;
for (int i = 0; i < len; i++) {
//这里tmp一直在往后移动(print_int中体现)
tmp = p_fun(tmp);
}
printf("\n");
}
int main() {
int arr1[] = { 4, 4213, 54, 1245, 1, 45, 2 };
int len1 = sizeof(arr1) / sizeof(arr1[0]);
double arr2[] = { 134.1, 42.42, 4132.42, 12.543 };
int len2 = sizeof(arr2) / sizeof(arr2[0]);
struct Student arr3[] = { {"shen",20},{"chen",18},{"zhang",19} };
int len3 = sizeof(arr3) / sizeof(arr3[0]);
print_arr(arr1, len1, print_int);
print_arr(arr2, len2, print_double);
print_arr(arr3, len3, print_stu);
return 0;
}
通过q_sort
排序理解void*
以及仿函数
// 这里传入的是指向char*类型的指针(即char**)
int cmp_str(const void* p1, const void* p2) {
const char* str1 = *(const char* *)(p1);
const char* str2 = *(const char* *)(p2);
/*int len1 = sizeof(str1) / sizeof(str1[0]);
int len2 = sizeof(str2) / sizeof(str2[0]);
int len = len1 < len2 ? len1 : len2;
for (int i = 0; i < len; i++) {
if (str1[i] != str2[i]) {
return str1[i] - str2[i];
}
}*/
if (strcmp(str1, str2) < 0) {
return -1;
}
else if(strcmp(str1, str2) > 0){
return 1;
}
return 0;
}
// 这里传入的是指向int*类型的指针
int cmp_int(const void* p1, const void* p2) {
int num1 = *(const int*)p1;
int num2 = *(const int*)p2;
if (num1 < num2) {
return -1;
}
else if(num1 > num2){
return 1;
}
else {
return 0;
}
}
int cmp_stu_age(const void* p1, const void* p2) {
const struct Student* stu_p1 = (const struct Student*)p1;
const struct Student* stu_p2 = (const struct Student*)p2;
if (stu_p1->age > stu_p2->age) {
return 1;
}
else if (stu_p1->age < stu_p2->age) {
return -1;
}
else {
return 0;
}
}
int cmp_stu_name(const void* p1, const void* p2) {
const struct Student* stu_p1 = (const struct Student*)p1;
const struct Student* stu_p2 = (const struct Student*)p2;
if (strcmp(stu_p1->name, stu_p2->name) > 0) {
return 1;
}
else if (strcmp(stu_p1->name, stu_p2->name) < 0) {
return -1;
}
else {
return 0;
}
}
int main() {
int arr[] = { 4,1,63,561,35,6357,6,87 };
int len1 = sizeof(arr) / sizeof(arr[0]);
qsort(arr, len1, sizeof(int), cmp_int);
for (int num : arr) {
printf("%d ", num);
}
printf("\n");
// 字符串存放在数据区,不可改变
const char* str[] = {
"rqew","ffs","bcvn","vxbz",
"rewf","fdsa","bav","vsag"
};
int len2 = sizeof(str) / sizeof(str[0]);
qsort(str, len2, sizeof(char*), cmp_str);
for (const char* s : str) {
printf("%s\n", s);
}
struct Student arr3[] = { {"shen",20},{"chen",18},{"zhang",19} };
int len3 = sizeof(arr3) / sizeof(arr3[0]);
qsort(arr3, len3, sizeof(struct Student), cmp_stu_age);
for (struct Student stu : arr3) {
printf("%s %d\n", stu.name, stu.age);
}
qsort(arr3, len3, sizeof(struct Student), cmp_stu_name);
for (struct Student stu : arr3) {
printf("%s %d\n", stu.name, stu.age);
}
}
关于命令行参数
// argv是一个数组,元素是char*,0号元素为应用程序名,剩余元素为命令行参数
// argc表示参数数量(包括应用程序名)
int main(int argc, char* argv[], char* env[]){
for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
argv[0][1] = '3'; // 可以改动,数据不在数据区,而在栈区
printf("%s\n", argv[0]);
for (int i = 0; env[i] != nullptr; i++) {
printf("%s\n", env[i]); // 打印系统环境变量
}
}
复制文件的程序
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]) {
if (argc < 3) {
printf("命令行参数不匹配!");
return 1;
}
//argv[0] = 3.exe,argv[1]=src.txt,argv[2]=dst.txt
FILE* fp_read = nullptr;
FILE* fp_write = nullptr;
errno_t read_flag = fopen_s(&fp_read, argv[1], "rb");
errno_t write_flag = fopen_s(&fp_write, argv[2], "wb");
if (fp_read == nullptr) {
printf("open file %s error : %d\n", argv[1], read_flag);
exit(1);
}
if (fp_write == nullptr) {
printf("open file %s error : %d\n", argv[2], write_flag);
exit(1);
}
// fp_read移动到文件末尾,从SEEK_END偏移0
fseek(fp_read, 0, SEEK_END);
//src文件大小,字节个数
int len = ftell(fp_read);
// fp_read移动到文件首
rewind(fp_read);// 等价于fseek(fp_read, 0, SEEK_SET);
printf("%s 长度: %d字节\n",argv[1], len);
if (len > 0) {
char* buff = (char*)malloc(sizeof(char) * (len+1));
fread(buff, sizeof(char), len, fp_read);
fwrite(buff, sizeof(char), len, fp_write);
printf("文件拷贝成功!");
}
fclose(fp_read);
fp_read = nullptr;
fclose(fp_write);
fp_write = nullptr;
return 0;
}