Skip to main content
 首页 » 编程设计

C语言笔记

2022年07月19日64bhlsheji

1.goto label; goto和label只能在同一个函数中!

2.打印log:

  #define log_printf(s,...) printf("RVC: %s():%d: " s, __func__, __LINE__, ##__VA_ARGS__)

3.setjmp和longjmp

非局部跳转语句:setjmp和longjmp函数。非局部指的是,这不是由普通C语言goto,语句在一个函数内实施的跳转,而是在栈上跳
过若干调用帧,返回到当前函数调用路径上的某一个函数中。
Int setjmp(jmp_buf env);                //返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值
Void longjmp(jmp_buf env,int val);
在希望返回到的位置调用setjmp,此位置在main函数中,因为直接调用该函数,所以其返回值为0. setjmp参数evn的类型是一个特殊
的类型jmp_buf.在使用longjmp跳转到setjmp中时,程序主动地退出了!相当于抛出一个异常退出!其实这两个函数可以模拟C++中的异常函数:
setjmp与longjmp结合使用时,它们必须有严格的先后执行顺序,也即先调用setjmp函数,之后再调用longjmp函数,以恢复到先
前被保存的“程序执行点”。否则,如果在setjmp调用之前,执行longjmp函数,将导致程序的执行流变的不可预测,很容易导致程序
崩溃而退出.

4.container_of的第三个参数必须是具有实体的!

//struct max9288_priv *priv = container_of(client, struct max9288_priv, client); /*error: struct max9288_priv应该有client实体才行,而不是指针!!!*/

struct max9288_priv *priv = container_of(sd, struct max9288_priv, subdev);

若第三个参数是指针怎么使用呢,下面写两个其变体

(1) 取消其类型检查,然后取number的地址后使用强制类型转换

(2) 改动一下类型转换那里检查的类型

例子:

#include <stdio.h> 
 
#define offsetof(TYPE, MEMBER) ((unsigned long ) &((TYPE *)0)->MEMBER) 
 
#if 0 
//original 
#define container_of(ptr, type, member) ({            \ 
    const typeof(((type *)0)->member) * __mptr = (ptr);    \ 
    (type *)((char *)__mptr - offsetof(type, member)); }) 
#endif 
 
//去掉类型检查 
#define container_of(ptr, type, member) ({ (type *)((char *)ptr - offsetof(type, member)); }) 
 
//更改类型 
#define container_of_ptr(ptr, type, member) ({            \ 
    const typeof(((type *)0)->member)  __mptr = (ptr);    \ 
    (type *)((char *)__mptr - offsetof(type, member)); }) 
 
 
struct stu { 
    char *name; 
    int id; 
    int class; 
    int *parents; 
    int grade; 
}; 
 
int g_parents = 1122; 
 
void main() 
{ 
 
    struct stu stu1; 
    stu1.name = "XueBaochai"; 
    stu1.id = 10; 
    stu1.class = 9; 
    stu1.parents = &g_parents; 
    stu1.grade = 149; 
 
    int *par = (int *)&stu1.parents; 
 
    struct stu *pstu1 = container_of_ptr(par, struct stu, parents); 
    struct stu *pstu2 = container_of(par, struct stu, parents); 
 
    printf("pstu1->name = %s\n", pstu1->name); 
    printf("pstu2->name = %s\n", pstu2->name); 
} 
 
/* 
# gcc container_of_test.c -o pp 
# ./pp 
pstu1->name = XueBaochai 
pstu2->name = XueBaochai 
*/

5.printf("=======2========%s\n");  会Segmentation fault (core dumped), 因为%s没有指定地址。可变参数函数对参数检查不严格,所以编译不会报错但运行有错!

6.glib---字符串处理函数
https://blog.csdn.net/hpu11/article/details/62063353

 7.可变参数函数解析

#include "stdio.h"    
#include "stdarg.h" 
 
void gst_caps_new_full_valist (int arg, va_list var_args) 
{ 
    while (arg) { 
        printf("arg=%d\n", arg); 
        arg = va_arg(var_args, int); /*meet first non-int exit!!!*/ 
    } 
} 
 
int gst_caps_new_full(int arg1, ...) 
{ 
  va_list var_args; 
 
  va_start (var_args, arg1); 
  gst_caps_new_full_valist(arg1, var_args); 
  va_end (var_args); 
} 
 
 
int main() 
{ 
    gst_caps_new_full(1,2,3,4,5,6,7,1.25,8,9,0); 
} 
 
运行结果: 
[root@sfl c_test]# ./pp 
arg=1 
arg=2 
arg=3 
arg=4 
arg=5 
arg=6 
arg=7

4.#define to_usb_driver(d)   container_of(d, struct usb_driver, drvwrap.driver)  还可以是变量的子成员 

5.头文件直接展开做为数组元素

static struct us_unusual_dev us_unusual_dev_list[] = { 
    include "unusual_devs.h" 
{ }    /* Terminating entry */ 
};

6. 编译运行宏

__LINE__ 在源代码中插入当前源代码行号
__FILE__ 在源代码中插入当前源代码文件名
__DATE__ 在源代码中插入当前编译日期〔注意和当前系统日期区别开来〕
__TIME__ 在源代码中插入当前编译时间〔注意和当前系统时间区别开来〕
__STDC__ 当要求程序严格遵循ANSIC标准时该标识符被赋值为1。

7. 怎样判断一个字符是数字、字母或其它类别的符号

在头文件ctype.h中定义了一批函数,它们可用来判断一个字符属于哪一类别。下面列出了这些函数:

--------------------------------------------------------------------------------------- 
   函数         字符类别               返回非零值的字符 
--------------------------------------------------------------------------------------- 
  isdigit()     十进制数               0--9 
  isxdigit()    十六进制数             0--9,a—f,或A--F 
  isalnum()     字母数字符号           0--9,a--Z,或A--Z 
  isalpha()     字母                   a—z或A--Z 
  islower()     小写字母               a—z 
  isupper()     大写字母               A--Z 
  isspace()     空白符                 空格符,水平制表符,垂直制表符,换行符,换页符,或回车符 
  isgraph()     非空白字符             任何打印出来不是空白的字符(ASCII码从21到7E) 
  isprint()     可打印字符             所有非空白字符,加上空格符 
  ispunct()     标点符                 除字母数字符号以外的所有非空白字符 
  iscntrl()     控制字符               除可打印字符外的所有字符(ASCII码从00到1F,加上7F) 
  isascii(测试字符是否为ASCII 码字符)  
  toascii(将整型数转换成合法的ASCII 码字符)  
  tolower(将大写字母转换成小写字母)  
  toupper(将小写字母转换成大写字母) 
  isalnum(检查参数c是否为英文字母或阿拉伯数字)

8.结构体中的匿名成员可以直接访问

#include <stdio.h> 
 
struct audit_field { 
    int type; 
    union { 
        int    gid; 
        struct { 
            char lsm_str; 
            struct { 
                int inner; 
            }; 
        }; 
    }; 
    int op; 
}; 
 
struct audit_data { 
    int type; 
    union { 
        int    gid; 
        struct { 
            char lsm_str; 
            struct { 
                int inner; 
            }is; 
        }os; 
    }u; 
    int op; 
}; 
 
 
void main() { 
    struct audit_field audit; 
    audit.inner = 2; 
 
    struct audit_data data; 
    data.u.os.is.inner = 3; 
 
    printf("audit.inner=%d\n", audit.inner); 
 
    printf("data.u.os.is.inner=%d\n", data.u.os.is.inner); 
}

9.使用getenv()函数获取指定的系统环境变量,这些环境变量是可以使用env工具查看到的,也是可以通过echo $XX打印出来的。

#include <stdlib.h> 
#include <stdio.h> 
 
void main() { 
    const char *name = "PATH"; 
 
    char *value = getenv(name); 
 
    printf("%s=%s\n", name, value); 
 
}

10.获取程序用户ID

uid_t是定义在头文件sys/types.h中,getuid()函数返回一个调用程序的真实用户ID,一般来说,这个函数都是会调用成功的。当使用root身份执行范例程序时uid is 0.

#include<stdio.h> 
#include<stdlib.h> 
#include <sys/types.h> 
#include <pwd.h> 
#include <stdio.h> 
#include <unistd.h> 
 
void main() 
{ 
    printf("UID is: %d\n", getuid()); 
    printf("EUID is: %d\n", geteuid()); 
}

参考:http://blog.csdn.net/wykwdy007/article/details/6535322 有例子。

uid_t是定义在头文件sys/types.h中,getuid()函数返回一个调用程序的真实用户ID,一般来说,这个函数都是会调用成功的。当使用root身份执行范例程序时uid is 0.

#include<stdio.h>#include<stdlib.h>#include <sys/types.h>#include <pwd.h>#include <stdio.h>#include <unistd.h>
void main(){printf("UID is: %d\n", getuid());printf("EUID is: %d\n", geteuid());}


本文参考链接:https://www.cnblogs.com/hellokitty2/p/7816816.html