这周写题时 发现c语言中的有些东西忘得比较多 写篇博客回忆一下
1. 关于指针
1)空指针与未初始化指针的区别:
空指针可以保证不指向任何函数或对象 一般倾向于用NULL表示空指针
而未初始化的指针则可能指向任何地方 所以指针一定要初始化
int *p = NULL; // 空指针
int *p; //指针未初始化 错误
*p = 5;
2)函数指针与指针函数的区别
c语言在编译时,每个函数都有一个入口地址 该地址就是函数指针所指向的地址
函数指针的生声明方法为:
( 返回值类型 )( *指针变量名 ) ( 形参列表 )
int func ( int x ) // 声明一个函数
int ( * f) (int a) // 声明一个函数指针
f = func;
指针函数:是指返回值为指针的函数,即本质是一个函数
3) 数组指针与指针数组
数组指针:数组指针是一个指向数组的指针 首先它是一个指针 然后这个指针指向数组 在32位机下占4个字节 因为它是一个指针 指针占4个字节
int (*p1)[10];
"( )“的优先级高于”[ ]" 所以p1先于*结合 构成一个指针
指针数组:指针数组是指一个数组里面存放的是指针类型的数据 即每个元素都是指针
int *p1[10];
要知道 " [] “的优先级要高于” * " 所以p1先于“[ ]”结合 构成一个数组 这个数组里面包含10个int类型的指针
放两张图理解一下
4)指针应用
static void *threadfuc(void *arg)
{
char *s=(char *)arg;
printf("%s",s); // 传递指针参数进去 printf函数对指针解引用
return (void *)strlen(s);
}
int main()
{
pthread_t t1;
void *res;
int s;
s=pthread_create(&t1, NULL, threadfuc, "hello world\n");
if (s != 0) {
printf("errno:pthread_create\n");
}
s=pthread_join(t1,&res); // 第二个参数为void**arg,因为threadfuc的返回值是一个void *,pthread_join负责把这个void *的值带出来,也就是赋值给res,所以这里用void **
if (s != 0)
printf("errno:pthread_join\n");
printf("thread return %ld\n",(long)res);
exit(EXIT_SUCCESS);
}
因为c的语法表达能力的限制,所以线程函数原型不好定义,为了最大限度的通用,传入void *
指针,返回void *
指针以满足所有人的需求,如果你要传入多个值,返回多个值,你就要定义传入的结构体,定义传出的结构体,malloc内存来填充结构体传入或者返回,如果你要传递的参数小于指针长度,可以用指针变量本身来带数据进出,比如这个实现,指针本身的值就是长度,如果你尝试解引用就挂了;
当看到一个指针的时候,不见得非要把人家解引用,首先它是一个8字节的空间,你可以拿这8个字节存任何东西,但是你要解引用,就必须是合法地址,否则段错误伺候;
2. getch与getchar
getchar:当程序调用getchar时,程序就等着用户按键。用户输入的字符被存放在键盘缓冲区内,直到用户按回车键为止(回车键也保存在缓冲区内)
当用户键入回车后,getchar才开始从stdio流中每次读入一个字符
getchar函数的返回值是用户输入的第一个字符的ASCII码,若文件结尾(End-Of-File)则返回-1(EOF),且将用户输入的字符回显到屏幕
如果用户在按回车键之前不止输入了一个字符,其他字符会保存在键盘缓冲区内,等待后续getchar调用
也就是说,后续的getchar程序调用不会等待用户按键,而是直接读取缓冲区内的字符,直到缓冲区内的字符读完,才会等待用户按键
getch:接受任意一个键的输入,不用按回车就返回,且该函数的输入不会自动输出到屏幕上,需要用putchar()输出函数显示
getch与getchar基本功能相同,差别是getch直接从键盘获取键值,不等待用户按回车,只要用户按一个键,getch就立刻返回, getch返回值是用户输入的ASCII码,出错返回-1.输入的字符不会回显在屏幕上 getch函数常用于程序调试中,在调试时,在关键位置显示有关的结果以待查看,然后用getch函数暂停程序运行,当按任意键后程序继续运行
getchar() 用#include<stdio.h>
getch() 用#include<conio.h>
3. gets与scanf的区别
二者都是从终端读入字符串 功能为:
1、 gets功能为读入一行,并将换行符转换为字符串结束符
2、 scanf("%s",s);读入时,遇到空白字符,包括空格,制表符,换行符时均会停止输入
从功能上可以看出不同之处:
1 终止条件不同 gets只有遇到\n时才会结束输入,而scanf遇到空格或制表符时,也会结束输入
比如输入
"test string\n"
用gets得到的字符串为"test string", 二用scanf得到的是"test"。
2 终止后,对终止字符处理不同
比如输入为
"test\nabc"
执行gets后,\n不会留在缓冲区中,即这时调用getchar得到的字符是’a’
执行scanf后,\n会留在缓冲区,这时调用getchar得到的字符是’\n’
4. 内核代码风格
前几天被学长吐槽代码丑 发现这一块真的是不咋注意 然后在网上查了一下 可参考这篇文档
更正一下自己的代码风格
https://www.kernel.org/doc/html/v4.14/translations/zh_CN/coding-style.html