陕煤化建设集团铜川分公司网站卡易售网站建设

张小明 2026/1/15 16:46:04
陕煤化建设集团铜川分公司网站,卡易售网站建设,宁波建网站需要什么,删除wordpress修订版本一、基本概念 1. C语言开发环境是什么#xff1f;什么平台#xff0c;什么编辑器#xff0c;什么编译器#xff1f; 回答#xff1a; 平台#xff1a;主要使用Linux/UNIX系统#xff0c;Windows和嵌入式系统也常用 编辑器#xff1a;常用Vim、VS Code、Sublime Text…一、基本概念1. C语言开发环境是什么什么平台什么编辑器什么编译器回答平台主要使用Linux/UNIX系统Windows和嵌入式系统也常用编辑器常用Vim、VS Code、Sublime Text、Eclipse CDT等编译器GCCGNU Compiler CollectionLinux/UNIX下最常用Clang/LLVM苹果平台常用编译速度快MSVCWindows平台Visual Studio的编译器嵌入式专用编译器如Keil、IAR等用于ARM、单片机开发2. 为什么用C语言开发与如Python、Java的相比有什么区别回答C语言特点编译型语言直接编译成机器码执行速度快接近硬件可以直接操作内存、硬件手动内存管理效率高但风险大指针操作灵活但容易出错与Python/Java对比性能C语言性能最好Python最慢开发效率Python/Java开发快C语言开发慢安全性C语言容易有内存泄漏、缓冲区溢出应用领域C操作系统、嵌入式、驱动PythonAI、Web、数据分析Java企业应用、Android、大型系统3. 如何组织大型C语言项目中的代码使用makefile怎么管理回答代码组织结构project/ ├── include/ # 头文件 │ ├── utils.h │ └── data.h ├── src/ # 源文件 │ ├── main.c │ ├── utils.c │ └── data.c ├── lib/ # 库文件 ├── Makefile # 构建文件 └── README.mdMakefile示例makefile# 编译器和选项 CC gcc CFLAGS -Wall -g -I./include LDFLAGS -lm # 目标文件和源文件 TARGET myapp SRCS $(wildcard src/*.c) OBJS $(SRCS:.c.o) # 构建规则 $(TARGET): $(OBJS) $(CC) -o $ $(OBJS) $(LDFLAGS) %.o: %.c $(CC) $(CFLAGS) -c $ -o $ # 清理 clean: rm -f $(OBJS) $(TARGET) # 伪目标 .PHONY: clean二、基本语法1. typedef和#define分别有什么作用有什么区别回答#define预处理器指令简单的文本替换#define PI 3.14 // 定义常量 #define MAX(a,b) ((a)(b)?(a):(b)) // 定义宏 #define INT_PTR int* // 定义类型不推荐 int* a, b; // a是指针b是int INT_PTR c, d; // c是指针d是int有歧义typedef创建类型别名是编译时行为typedef int* IntPtr; // 创建类型别名 IntPtr e, f; // e和f都是指针 typedef struct { int x; int y; } Point; // 定义结构体类型主要区别作用时间#define在预处理阶段typedef在编译阶段类型安全typedef更安全有类型检查作用域#define无作用域typedef有作用域使用建议定义类型用typedef定义常量或简单宏用#define2. 什么是枚举类型如何定义和使用枚举类型回答定义枚举// 定义方式1先定义枚举类型再声明变量 enum Weekday { MONDAY, // 默认0 TUESDAY, // 1 WEDNESDAY, // 2 THURSDAY, // 3 FRIDAY, // 4 SATURDAY, // 5 SUNDAY // 6 }; enum Weekday today; // 定义方式2定义时赋值 enum Color { RED 1, GREEN 2, BLUE 4 }; // 定义方式3使用typedef简化 typedef enum { STATE_IDLE, STATE_RUNNING, STATE_ERROR } State; State current_state;使用枚举enum Color color RED; if (color RED) { printf(红色\n); } // 枚举可以赋值给整数 int code color; // 1 // 整数可以强制转换为枚举但类型不安全 color (enum Color)2; // GREEN枚举优点提高代码可读性有类型检查比宏安全编译器可以优化3. 全局变量和局部变量可以重名吗需要注意什么回答可以重名但局部变量会隐藏全局变量#include stdio.h int count 100; // 全局变量 void func() { int count 50; // 局部变量隐藏全局变量 printf(局部count: %d\n, count); // 输出50 { int count 20; // 新的局部变量隐藏外层局部变量 printf(块内count: %d\n, count); // 输出20 } } int main() { printf(全局count: %d\n, count); // 输出100 func(); return 0; }注意事项作用域规则局部变量优先于全局变量访问全局变量使用extern声明或使用作用域解析操作符C不支持::extern int count; // 引用全局变量最佳实践避免重名提高代码可读性全局变量加前缀g_如g_count尽量减少使用全局变量4. if, switch, while, break, continue用法回答if语句// 基本形式 if (condition) { // 条件为真执行 } else if (condition2) { // 否则如果条件2为真执行 } else { // 以上都不满足执行 } // 嵌套if if (x 0) { if (y 0) { printf(第一象限\n); } }switch语句switch (expression) { case constant1: // 代码块 break; // 必须用break否则会继续执行 case constant2: // 代码块 break; default: // 可选 // 默认代码块 break; } // 注意expression必须是整型或枚举类型 // case后面必须是常量表达式while循环// while循环先判断后执行 int i 0; while (i 10) { printf(%d , i); i; } // do-while循环先执行后判断 int j 0; do { printf(%d , j); j; } while (j 10);break和continue// break跳出当前循环或switch for (int i 0; i 10; i) { if (i 5) { break; // 跳出循环 } printf(%d , i); // 输出0 1 2 3 4 } // continue跳过本次循环剩余部分 for (int i 0; i 10; i) { if (i % 2 0) { continue; // 跳过偶数 } printf(%d , i); // 输出1 3 5 7 9 } // 多层循环中的break for (int i 0; i 3; i) { for (int j 0; j 3; j) { if (j 1) { break; // 只跳出内层循环 } printf((%d,%d) , i, j); } } // 输出(0,0) (1,0) (2,0)三、函数1. 手撕strcpy、strcat、strcmp、memcpy考虑内存重叠问题回答strcpy实现char* my_strcpy(char* dest, const char* src) { if (dest NULL || src NULL) return NULL; char* ret dest; while ((*dest *src) ! \0); return ret; }strcat实现char* my_strcat(char* dest, const char* src) { if (dest NULL || src NULL) return NULL; char* ret dest; // 找到dest的结尾 while (*dest ! \0) dest; // 追加src while ((*dest *src) ! \0); return ret; }strcmp实现int my_strcmp(const char* str1, const char* str2) { if (str1 NULL || str2 NULL) return 0; while (*str1 (*str1 *str2)) { str1; str2; } return *(unsigned char*)str1 - *(unsigned char*)str2; }memcpy实现考虑内存重叠void* my_memcpy(void* dest, const void* src, size_t n) { if (dest NULL || src NULL || n 0) return dest; char* d (char*)dest; const char* s (const char*)src; // 检查内存重叠 if (d s d s n) { // 从后向前拷贝处理重叠情况 d d n - 1; s s n - 1; while (n--) { *d-- *s--; } } else { // 从前向后拷贝 while (n--) { *d *s; } } return dest; }内存重叠示例char str[20] hello,world; // 重叠情况目标地址在源地址范围内 my_memcpy(str 5, str, 7); // 正常拷贝 // 标准memcpy可能出错my_memcpy正确处理2. 带参宏和函数的区别回答区别对比特性带参宏函数处理阶段预处理阶段编译/运行阶段类型检查无类型检查有类型检查调用开销无调用开销代码展开有调用开销压栈/弹栈调试难以调试容易调试代码大小可能增大代码代码复用副作用容易有副作用相对安全示例// 带参宏 #define SQUARE(x) ((x) * (x)) int a 5; int b SQUARE(a); // 展开((a) * (a))a自增两次 // 函数 int square(int x) { return x * x; } int c square(a); // 安全a只自增一次3. 内核中出现的inline是什么意思回答inline函数建议编译器将函数代码直接插入调用处避免函数调用开销// 声明inline函数 static inline int max(int a, int b) { return (a b) ? a : b; } int main() { int x 10, y 20; int result max(x, y); // 编译器可能直接展开为(x y) ? x : y return 0; }内核中使用原因性能要求高减少函数调用开销代码体积小函数体通常很短编译器建议只是建议编译器可能忽略注意事项inline只是建议最终由编译器决定不适合复杂函数可能导致代码膨胀定义通常在头文件中加上static4. 带参宏实现两个数比较回答// 比较两个数返回较大值 #define MAX(a, b) ((a) (b) ? (a) : (b)) // 比较两个数返回较小值 #define MIN(a, b) ((a) (b) ? (a) : (b)) // 比较是否相等考虑浮点数 #define FLOAT_EQUAL(a, b, eps) (fabs((a) - (b)) (eps)) // 使用示例 int x 10, y 20; int max_val MAX(x, y); // 20 int min_val MIN(x, y); // 10 // 注意宏参数要加括号避免运算符优先级问题 #define SQUARE(x) ((x) * (x)) int z SQUARE(3 2); // 正确((32)*(32)) 255. 带参宏实现两个数交换回答// 使用临时变量通用支持所有类型 #define SWAP(a, b) do { \ typeof(a) temp a; \ a b; \ b temp; \ } while(0) // 不使用临时变量仅限整数 #define SWAP_INT(a, b) do { \ a a ^ b; \ b a ^ b; \ a a ^ b; \ } while(0) // 加减法交换仅限数值类型 #define SWAP_ADD(a, b) do { \ a a b; \ b a - b; \ a a - b; \ } while(0) // 使用示例 int x 10, y 20; SWAP(x, y); // x20, y10 // 注意do{...}while(0)的作用 // 1. 确保宏在if/else语句中正确使用 // 2. 避免分号问题 if (condition) SWAP(x, y); // 正确展开为一个语句块 else // ...6. 函数是如何调用的回答函数调用过程int add(int a, int b) { return a b; } int main() { int x 5, y 10; int result add(x, y); // 函数调用 return 0; }调用步骤参数传递将实参x, y压入栈保存现场保存返回地址和当前寄存器跳转跳转到函数入口地址函数执行执行函数体返回值将结果存入指定寄存器如eax恢复现场恢复寄存器跳回调用处清理栈调用者清理参数空间栈帧结构高地址 ┌─────────────┐ │ 调用者信息 │ ├─────────────┤ │ 参数n │ ├─────────────┤ │ ... │ ├─────────────┤ │ 参数1 │ ├─────────────┤ │ 返回地址 │ ├─────────────┤ │ 旧BP/EBP │ ← 当前BP ├─────────────┤ │ 局部变量 │ ├─────────────┤ │ 临时空间 │ └─────────────┘ 低地址四、函数参数传递1. 解释值传递和指针传递的区别回答值传递Pass by Valuevoid change_value(int a) { a 100; // 只修改局部副本 } int main() { int x 10; change_value(x); printf(%d\n, x); // 输出10x未改变 return 0; }传递参数的副本函数内修改不影响原值适用于小型数据指针传递Pass by Pointer/Referencevoid change_value_by_pointer(int* p) { *p 100; // 修改指针指向的值 } int main() { int x 10; change_value_by_pointer(x); printf(%d\n, x); // 输出100x被修改 return 0; }传递变量的地址函数内可以通过指针修改原值适用于大型数据或需要修改的情况关键区别数据拷贝值传递拷贝整个数据指针传递只拷贝地址修改原值值传递不能修改指针传递可以性能大型数据用指针更高效安全性指针传递有风险空指针、野指针2. 如何通过指针实现指针传递回答二级指针示例void allocate_memory(int** ptr, int size) { *ptr (int*)malloc(size * sizeof(int)); if (*ptr ! NULL) { for (int i 0; i size; i) { (*ptr)[i] i; // 注意括号优先级 } } } int main() { int* array NULL; int size 10; // 传递指针的地址二级指针 allocate_memory(array, size); if (array ! NULL) { for (int i 0; i size; i) { printf(%d , array[i]); } free(array); } return 0; }为什么要用二级指针// 错误一级指针无法修改调用者的指针 void wrong_allocate(int* ptr, int size) { ptr (int*)malloc(size * sizeof(int)); // 只修改局部副本 } // 正确二级指针可以修改调用者的指针 void correct_allocate(int** ptr, int size) { *ptr (int*)malloc(size * sizeof(int)); // 修改指向的内容 }3. 一个函数传入一个参数怎么返回两个参数回答方法1通过指针参数返回// 返回两个值通过指针参数 void get_two_values(int input, int* out1, int* out2) { *out1 input * 2; // 第一个返回值 *out2 input * 3; // 第二个返回值 } int main() { int value 10; int result1, result2; get_two_values(value, result1, result2); printf(%d, %d\n, result1, result2); // 20, 30 return 0; }方法2返回结构体typedef struct { int first; int second; } TwoValues; TwoValues get_two_values_struct(int input) { TwoValues result; result.first input * 2; result.second input * 3; return result; } int main() { int value 10; TwoValues results get_two_values_struct(value); printf(%d, %d\n, results.first, results.second); // 20, 30 return 0; }方法3返回指针需注意内存管理int* get_two_values_pointer(int input, int* size) { int* result (int*)malloc(2 * sizeof(int)); if (result ! NULL) { result[0] input * 2; result[1] input * 3; *size 2; } return result; // 调用者需要释放内存 }五、递归函数1. 你用过递归吗回答用过常见应用场景数学计算阶乘、斐波那契数列数据结构树的遍历前序、中序、后序算法快速排序、归并排序、汉诺塔文件系统目录遍历示例阶乘计算// 递归实现 unsigned long long factorial_recursive(int n) { if (n 1) return 1; return n * factorial_recursive(n - 1); } // 迭代实现 unsigned long long factorial_iterative(int n) { unsigned long long result 1; for (int i 2; i n; i) { result * i; } return result; }2. 递归函数的优缺点是什么回答优点代码简洁适合解决分治问题表达力强更符合问题本质如树遍历易于理解对某些问题更直观缺点性能开销大函数调用开销栈空间消耗可能栈溢出深度递归导致栈溢出重复计算如朴素斐波那契递归有大量重复计算调试困难调用层次深时难以调试示例斐波那契数列// 朴素递归效率低大量重复计算 int fib_recursive(int n) { if (n 2) return 1; return fib_recursive(n-1) fib_recursive(n-2); } // 优化记忆化搜索 int fib_memo[100] {0}; int fib_memoization(int n) { if (n 2) return 1; if (fib_memo[n] ! 0) return fib_memo[n]; fib_memo[n] fib_memoization(n-1) fib_memoization(n-2); return fib_memo[n]; }3. 如何避免递归中的无限循环回答预防措施明确递归终止条件确保每次递归都向终止条件前进添加递归深度限制使用迭代替代递归示例安全递归函数#include stdio.h #include stdbool.h #define MAX_DEPTH 1000 // 安全的递归函数 int safe_recursive(int n, int depth) { // 1. 检查递归深度 if (depth MAX_DEPTH) { printf(递归深度超过限制\n); return -1; } // 2. 明确的终止条件 if (n 0) { return 0; } // 3. 确保递归向终止条件前进 return safe_recursive(n - 1, depth 1) n; } // 迭代替代递归 int iterative_solution(int n) { int result 0; while (n 0) { result n; n--; } return result; } int main() { int result safe_recursive(10, 0); printf(结果%d\n, result); return 0; }常见错误// 错误缺少终止条件 void infinite_loop() { printf(无限递归...\n); infinite_loop(); // 没有终止条件 } // 错误终止条件永远不会达到 void wrong_condition(int n) { if (n 10) return; // 假设是终止条件 wrong_condition(n 2); // 但n从1开始1,3,5,7,9,11...永远不会等于10 }六、数组1. 数组下标越界会导致什么问题回答问题表现访问非法内存读取或修改不属于程序的内存程序崩溃段错误Segmentation Fault数据损坏修改其他变量或函数返回地址安全漏洞缓冲区溢出攻击的根源示例int array[5] {1, 2, 3, 4, 5}; // 读取越界可能返回垃圾值 int value array[10]; // 未定义行为 // 写入越界可能破坏其他数据 array[10] 100; // 危险可能修改其他变量 // 常见错误循环条件错误 for (int i 0; i 5; i) { // 应该是 i 5 array[i] i; // i5时越界 } // 防止越界的方法 // 1. 使用常量定义数组大小 #define ARRAY_SIZE 5 int arr[ARRAY_SIZE]; for (int i 0; i ARRAY_SIZE; i) {} // 2. 计算数组元素个数 int arr[] {1, 2, 3, 4, 5}; int size sizeof(arr) / sizeof(arr[0]);2. 多维数组在内存中的存储方式是什么回答按行存储Row-major Orderint matrix[3][4] { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };内存布局地址: 内容 base: 1 (matrix[0][0]) base4: 2 (matrix[0][1]) base8: 3 (matrix[0][2]) base12: 4 (matrix[0][3]) base16: 5 (matrix[1][0]) base20: 6 (matrix[1][1]) ... base44: 12 (matrix[2][3])计算元素地址c复制下载// 对于int arr[M][N] // arr[i][j]的地址 base (i * N j) * sizeof(int) // 示例访问 int value *(*(matrix 1) 2); // matrix[1][2] 7 int* ptr matrix[0][0]; // 指向第一个元素 int seventh ptr[1 * 4 2]; // 等价于matrix[1][2]验证存储方式void print_memory_layout() { int arr[2][3] {{1, 2, 3}, {4, 5, 6}}; int* p (int*)arr; // 转换为一级指针 printf(按行存储验证\n); for (int i 0; i 6; i) { printf(arr[%d] %d\n, i, p[i]); } // 输出1 2 3 4 5 6 }3. 你知道字符串描述一下回答C语言中的字符串本质以\0空字符结尾的字符数组表示字符数组或字符指针特点不是内置类型通过标准库函数操作字符串表示方式// 方式1字符数组 char str1[] Hello; // 自动添加\0 char str2[6] {H,e,l,l,o,\0}; // 方式2字符指针 char* str3 Hello; // 字符串常量只读 char str4[] Hello; // 可修改的副本 // 字符串长度 int len strlen(str1); // 5不包括\0 int size sizeof(str1); // 6包括\0字符串操作函数#include string.h // 复制字符串 char dest[20]; strcpy(dest, Hello); // dest Hello strncpy(dest, World, 3); // 安全版本 // 连接字符串 strcat(dest, World); // dest Hello World // 比较字符串 int cmp strcmp(abc, abd); // 负值 // 查找字符 char* pos strchr(Hello, l); // 指向第一个l // 字符串转换 int num atoi(123); // 字符串转整数 double val atof(3.14); // 字符串转浮点数字符串安全问题// 危险缓冲区溢出 char buffer[10]; strcpy(buffer, 这是一个很长的字符串); // 溢出 // 安全使用带长度限制的函数 strncpy(buffer, 安全字符串, sizeof(buffer)-1); buffer[sizeof(buffer)-1] \0; // 确保终止4. 数组和链表的区别回答对比表格特性数组链表内存分配连续内存块离散内存节点大小固定大小静态动态大小访问方式随机访问O(1)顺序访问O(n)插入/删除O(n)需要移动元素O(1)修改指针内存效率无额外开销有指针开销缓存友好是局部性原理否实现复杂度简单较复杂代码示例// 数组 int array[100]; // 固定大小 array[50] 100; // 直接访问 // 链表节点 typedef struct Node { int data; struct Node* next; } Node; // 链表操作 Node* create_node(int value) { Node* node (Node*)malloc(sizeof(Node)); node-data value; node-next NULL; return node; } // 链表插入 void insert_after(Node* prev, int value) { Node* new_node create_node(value); new_node-next prev-next; prev-next new_node; } // 链表删除 void delete_after(Node* prev) { if (prev-next NULL) return; Node* temp prev-next; prev-next temp-next; free(temp); }选择建议用数组大小固定、频繁随机访问、追求性能用链表大小变化大、频繁插入删除、内存受限七、指针基础1. 什么是指针介绍一下你对指针的理解回答指针的核心概念本质存储内存地址的变量作用间接访问和操作数据大小与系统架构相关32位4字节64位8字节比喻理解变量房子存储数据指针房子的地址告诉你去哪里找数据基本概念int num 42; // 变量存储值42 int* ptr num; // 指针存储num的地址 printf(值: %d\n, num); // 42 printf(地址: %p\n, num); // 0x7fff... printf(指针值: %p\n, ptr); // 与num相同 printf(指向的值: %d\n, *ptr); // 42解引用指针的重要性动态内存管理malloc/free函数参数传递修改调用者变量数据结构链表、树、图等系统编程访问硬件、内存映射函数指针回调函数、策略模式2. 如何定义和初始化一个指针变量回答定义指针// 基本语法type* pointer_name; int* int_ptr; // 指向int的指针 char* char_ptr; // 指向char的指针 float* float_ptr; // 指向float的指针 void* void_ptr; // 通用指针可指向任何类型 // 定义多个指针注意*只作用于紧邻的变量 int *p1, *p2; // 两个指针 int* p3, p4; // p3是指针p4是int易错初始化指针// 方法1初始化为NULL推荐 int* ptr1 NULL; // 空指针 // 方法2指向已有变量 int num 10; int* ptr2 num; // 指向num // 方法3指向动态分配的内存 int* ptr3 (int*)malloc(sizeof(int) * 10); if (ptr3 ! NULL) { // 使用内存 free(ptr3); // 记得释放 } // 方法4指向数组 int arr[5] {1, 2, 3, 4, 5}; int* ptr4 arr; // 指向数组首元素 int* ptr5 arr[2]; // 指向第三个元素 // 方法5指向字符串常量只读 const char* str Hello; // 只读不能修改内容 // 错误初始化野指针 int* bad_ptr; // 未初始化指向随机地址 // *bad_ptr 10; // 危险未定义行为初始化最佳实践定义时立即初始化暂时不使用时初始化为NULL释放后置为NULL使用const保护只读数据3. 什么是地址运算符和解引用运算符*回答地址运算符获取变量地址int num 42; int* ptr num; // num获取num的地址 printf(num的值: %d\n, num); // 42 printf(num的地址: %p\n, num); // 如0x7ffc... printf(ptr的值: %p\n, ptr); // 与num相同解引用运算符*通过地址访问值int num 42; int* ptr num; printf(直接访问: %d\n, num); // 42 printf(间接访问: %d\n, *ptr); // 42解引用ptr // 通过指针修改变量 *ptr 100; // 等价于 num 100 printf(修改后: %d\n, num); // 100运算符优先级示例int arr[5] {1, 2, 3, 4, 5}; int* p arr; // 不同写法的等价性 printf(%d\n, arr[2]); // 3 printf(%d\n, *(arr 2)); // 3arr4.空指针是什么如何使用1. 空指针定义空指针不指向任何有效内存地址的指针在C中通常用NULL表示定义为(void*)02. 使用方式int* ptr NULL; // 定义并初始化为空指针 // 检查是否为空 if (ptr NULL) { printf(指针为空\n); } // 函数返回错误时常用 int* allocate_memory(int size) { if (size 0) return NULL; // 错误返回NULL return malloc(size); }5.野指针是什么如何避免1. 野指针定义野指针指向无效内存地址的指针常见原因未初始化、已释放、越界访问2. 如何避免// 1. 定义时初始化 int* p1 NULL; // ✅ 初始化为空 // 2. 释放后置空 int* p2 malloc(sizeof(int)); free(p2); p2 NULL; // ✅ 避免野指针 // 3. 不指向局部变量地址函数返回后失效 int* bad_ptr() { int local 10; return local; // ❌ 危险局部变量会被释放 }八、指针运算1. 指针可以进行哪些运算int arr[5] {1, 2, 3, 4, 5}; int* p arr; // ✅ 允许的运算 p; // 移动到下一个元素 p--; // 移动到上一个元素 p p 2; // 向后移动2个元素 p p - 1; // 向前移动1个元素 int diff p2 - p1; // 计算两个指针间的元素个数 // ❌ 不允许 // p * 2; // 不能乘除 // p / 2; // 不能乘除 // p p2; // 不能相加2. 如何比较两个指针int arr[5] {1, 2, 3, 4, 5}; int* p1 arr[1]; int* p2 arr[3]; // 比较地址需指向同一数组 if (p1 p2) { // ✅ p1在p2之前 printf(p1在p2之前\n); } if (p1 p2) { // ✅ 比较是否指向同一地址 printf(指向同一地址\n); } // 与NULL比较 int* ptr NULL; if (ptr NULL) { // ✅ 检查是否为空 printf(指针为空\n); }九、指针与数组1. 数组名和指针有什么关系int arr[3] {10, 20, 30}; // 数组名在大多数情况下退化为指向首元素的指针 printf(%p\n, arr); // 数组首地址 printf(%p\n, arr[0]); // 同上 // 但有两个例外 printf(%zu\n, sizeof(arr)); // 整个数组大小12字节 // sizeof(指针) 是指针本身大小4或8字节 int* p arr; printf(%zu\n, sizeof(p)); // 指针大小 // arr 是整个数组的地址类型为int(*)[3] printf(%p\n, arr); // 地址相同但类型不同2. 如何通过指针访问数组元素int arr[5] {1, 2, 3, 4, 5}; int* p arr; // 指向第一个元素 // 方法1下标法推荐 printf(%d\n, p[2]); // arr[2] // 方法2指针偏移 printf(%d\n, *(p 2)); // 同上 // 方法3移动指针 p 2; // p现在指向arr[2] printf(%d\n, *p); // 3 // 遍历数组 for (int i 0; i 5; i) { printf(%d , *(p i)); }3. 指针数组和数组指针的区别是什么// 1. 指针数组元素是指针的数组 int* ptr_array[3]; // 有3个int指针 int a1, b2, c3; ptr_array[0] a; ptr_array[1] b; ptr_array[2] c; // 2. 数组指针指向数组的指针 int (*array_ptr)[3]; // 指向有3个int的数组 int arr[3] {10, 20, 30}; array_ptr arr; // 指向整个数组 // 使用区别 printf(%d\n, *ptr_array[0]); // 访问第一个指针指向的值 printf(%d\n, (*array_ptr)[0]); // 访问数组第一个元素 // 简记看谁和标识符结合 // int* p[3]; → p[3]是数组int*是元素类型 → 指针数组 // int (*p)[3]; → *p是指针指向int[3] → 数组指针
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

自己电脑做网站服务器广域网访问深圳可以做网站的公司

目录 1、LIS331HH 核心电路:电源与接口的噪声控制 2、电源 LDO 选型:低静态电流适配低功耗场景 3、I2C 地址配置:解决多设备总线冲突 4、I2C 电平转换:兼容不同电压的主机 5、低功耗设计的小细节 6、调试时的踩坑总结 在导航、智能农业机器人或 VR/AR 设备中,高精度…

张小明 2026/1/11 12:31:00 网站建设

东莞高端网站建设费邯郸移动网站建设价格

为什么你的USB 2.0永远跑不满480 Mbps?真相藏在物理层的“电路迷宫”里你有没有试过把一个大文件拖进U盘,看着传输速度停留在35 MB/s左右,心里嘀咕:“不是说USB 2.0能到480 Mbps吗?那可是60 MB/s啊!”结果等…

张小明 2026/1/9 23:06:11 网站建设

用iis做的网站怎么更改端口哪个网站做推销产品

Proxmox VE终极优化指南:用pvetools打造高效虚拟化平台 【免费下载链接】pvetools pvetools - 为 Proxmox VE 设计的脚本工具集,用于简化邮件、Samba、NFS、ZFS 等配置,以及嵌套虚拟化、Docker 和硬件直通等高级功能,适合系统管理…

张小明 2026/1/13 8:40:08 网站建设

爱前端主图wordpress网站怎么做才能得到更好的优化

导语 【免费下载链接】UI-TARS-72B-SFT 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/UI-TARS-72B-SFT 字节跳动最新发布的UI-TARS-72B大模型以其原生GUI交互能力,标志着AI从文本交互迈向自主操作图形界面的关键突破,为企业自动…

张小明 2026/1/15 1:53:50 网站建设

网站开发品牌有哪些拼多多运营怎么做

构建可运营的OpenStack云环境 1. OpenStack API调用与监控 在使用诸如Nagios之类的监控平台进行API调用时,可通过插件脚本配置该平台使用Nova项目的nova CLI客户端。这些插件脚本可借助Python或其他脚本语言调用API,很多插件脚本可从 http://www.nagios.com 免费获取。例…

张小明 2026/1/9 15:21:02 网站建设

柬埔寨做网站网站莱芜招聘信息最新招聘2023年

目录 前言 一、KylinOS 系统安装(超详细步骤) ✅ 安装前置准备 ✅ 核心安装步骤 ✅ 安装后校验 二、KylinOS 基础必备:功能快捷键 核心命令速查 ✅ 一、桌面版 / 终端通用快捷键(效率翻倍) ✅ 二、KylinOS 高…

张小明 2026/1/8 7:36:53 网站建设