C零碎语法
目录
文章目录
- C零碎语法
- 1.函数指针
- 2.回调函数
- 3.数据拷贝
- 3.1静态内存分配![请添加图片描述](https://img-blog.csdnimg.cn/direct/54d44e32bb7944f0866d4ca1e2667ce8.png)### 4.1动态内存分配
- 字符串
- 6.sizeof()和strlen()的区别
- 7.strcpy()/strncpy()函数
- 7.1**strcpy() 函数用于将一个字符串复制到另一个字符串中**
- 7.2strncpy() 函数提供了一种更安全的方式来复制字符串
1.函数指针
#include <stdio.h>int max(int x, int y)
{return x > y ? x : y;
}int main(void)
{/* p 是函数指针 */int (* p)(int, int) = & max; // &可以省略int a, b, c, d;printf("请输入三个数字:");scanf("%d %d %d", & a, & b, & c);/* 与直接调用函数等价,d = max(max(a, b), c) */d = p(p(a, b), c); printf("最大的数字是: %d\n", d);return 0;
}
2.回调函数
函数指针作为某个函数的参数
以下是来自知乎作者常溪玲的解说:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
#include <stdlib.h>
#include <stdio.h>// 回调函数
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{for (size_t i=0; i<arraySize; i++)array[i] = getNextValue();
}// 获取随机值
int getNextRandomValue(void)
{return rand();
}int main(void)
{int myarray[10];/* getNextRandomValue 不能加括号,否则无法编译,因为加上括号之后相当于传入此参数时传入了 int , 而不是函数指针*/populate_array(myarray, 10, getNextRandomValue);for(int i = 0; i < 10; i++) {printf("%d ", myarray[i]);}printf("\n");return 0;
}
typedef struct {int status;void (*statusChange)(int status);
} JT_Device;JT_Device gDevice;void addCallbackFunc(JT_Device *device, void (*pstatusChange)(int status)) {device->statusChange = pstatusChange;
}void run(JT_Device *device) {device->status = 10;if(device->status == 1) { // 假设这里是1而不是1eif(device->statusChange != NULL) {device->statusChange(device->status);}}
}// 用户代码
void callBack(int status) {printf("Callback:\n");printf("status = %d\n", status);
}int main() {addCallbackFunc(&gDevice, callBack);run(&gDevice);return 0;
}
3.数据拷贝
3.1静态内存分配### 4.1动态内存分配
## 5.二维数组做形参
#include <stdio.h>int getArrayData(int (*p)[4], int lines, int columns) //数组指针来接收二维数组的地址,行数,列数
{ int data;return data = *(*(p + lines) + columns);
}int main()
{int array[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};int data;data = getArrayData(array, 1, 1); //获取array[1][1]的值return 0;
}
字符串
6.sizeof()和strlen()的区别
char str[] = "hello"; //结尾有'\0'
sizeof(str); //6,计算的是整个空间的长度
strlen(str); //5,只计算有效字符,会忽略结尾的'\0'char *p = "hello";
sizeof(p); //8,p是一个char *
strlen(p); //5
sizeof(p) 返回的是指针变量 p 的大小(地址的大小),在64位系统上通常是8字节。 strlen(p) 返回的是指针 p 指向的字符串的长度(不包括结尾的 \0),对于 "hello" 这个字符串是5。
7.strcpy()/strncpy()函数
7.1strcpy() 函数用于将一个字符串复制到另一个字符串中
#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello, World!";char dest[20];strcpy(dest, src); // 将src复制到destprintf("Destination: %s\n", dest);return 0;
}
注意:
strcpy() 不检查目标数组的大小,如果目标数组不够大,可能会导致缓冲区溢出,这是一个常见的安全问题。
它在复制完所有字符后不会在目标字符串的末尾添加空字符 \0,所以它假定源字符串以 \0 结尾。
7.2strncpy() 函数提供了一种更安全的方式来复制字符串
允许你指定最大复制的字符数
#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello, World!";char dest[20];strncpy(dest, src, 13); // 将src的前13个字符复制到dest// 确保字符串以空字符结尾dest[13] = '\0';printf("Destination: %s\n", dest);return 0;
}