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而不是1e
if(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复制到dest
printf("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;
}