
C语言高级编程
hello-linux
9年USB开发经验 + 6年网络及以太网驱动开发经验 + 2年PCIe驱动开发经验 + 5年romcode开发经验,专注网卡驱动、网络协议(TCP/IP)、USB驱动及应用开发。
展开
-
__weak 关键字的作用
加上了__weak 修饰符的函数,用户可以重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。所以我们可以在别的地方定义一个相同名字的函数,而不必也尽量不要修改之前的函数。函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。原创 2023-05-24 20:23:34 · 286 阅读 · 0 评论 -
C语言编译流程:预处理、编译、汇编、链接
流程: 预处理:展开头文件/宏替换/去掉注释/条件编译 (test.i main .i) 编译:检查语法,生成汇编 (test.s main .s) 汇编:汇编代码转换机器码 ...原创 2019-12-01 10:44:58 · 3389 阅读 · 1 评论 -
C语言高级编程:二维数组、指针的指针、数组指针、指针数组
1. 定义 int **p; 指针的指针 int (*p2)[5]; 数组指针,指向一个数组 int *array[5]; 指针数组,是一个int *类型数组 int array2[3][5]; 二维数组,数组的数组 2. 说明1)作为形参时,二维数组会被转换为数组指针,int a[][5] ==int (*a)[5]2)作为形参时,...原创 2019-11-03 20:57:05 · 1190 阅读 · 0 评论 -
C语言高级编程:如何确定一个变量是有符号还是无符号数
ANSI C中的整型升级:1)char,short int或者int型位段(bit-field),包括它们的有符号或无符号变型,2)以及枚举类型,可以使用在需要int或unsigned int的表达式中,3)如果int可以完整地表示源类型的所有值,那么该类型的值就转换为int,否则转换为unsigned int。ANSI C中的寻常算术转换:1)当执行算术运算时,操...原创 2019-11-03 20:51:58 · 3061 阅读 · 2 评论 -
C语言高级编程:汇编分析i++和++i
测试环境: Ubuntu 14.041. 代码#include <stdio.h>int main(){ int a; int b; int c; a = 1; b = a++; c = ++a; printf("b = %d, c = %d, a = %d\n", b, c, a);}2....原创 2019-11-03 20:48:38 · 1509 阅读 · 0 评论 -
C语言高级编程:数组和指针作为函数形参
测试环境:win10 x86-64gcc: x86_64-pc-cygwin1. 说明1)作为函数形参时(也只有这种情况),数组与指针等同,int *p = int a[],p和a在函数内部都是指针2)数组作为函数形参时将被转化为指向数组第一个元素的指针,无论是int a[10]还是int a[]形式的形参,在函数内部都是int *a形式指针3)没有办法直接将数组本身...原创 2019-11-03 20:43:15 · 5716 阅读 · 0 评论 -
C语言高级编程:指针和数组
1. 说明:1)变量p本身的地址在编译时确定,它是不变的;变量p存的内容是一个地址,在运行时才能确定,它是变化的2)数组arr的地址在编译时确定,它是不变的;数组arr村的内容是一个数据3)指针变量p能以数组的方式访问;数组arr能以指针的形式访问1.1 代码:#include <stdio.h>int main(void){ int ...原创 2019-11-03 20:38:24 · 763 阅读 · 0 评论 -
C语言高级编程:结构体中定义数组的“妙用”
1. 说明1)相同类型结构体变量可以直接赋值2)在结构体中定义一个数组,可以用赋值语句拷贝整个数组,这也是数组间赋值的一个间接实现方式3)在结构体中定义一个数组,可以传值调用的方法把它传递给函数做实参4)在结构体中定义一个数组,可以作为函数的返回类型2. 代码:#include <stdio.h>#define LEN 5struct array...原创 2019-11-03 20:32:51 · 10566 阅读 · 1 评论 -
C语言高级编程:字符串赋值的几种方式
1. 总结1)下面两种方式的字符串赋值均正确char str1[] = "hello str1";char *str2= "hello str2";char *str3; str3 = "hello str3";2)char str1[] = "hello str1"; 是将字符串赋值给数组,字符串存在数组里(这里是栈),可以修改字符串内容...原创 2019-10-08 11:22:39 · 18462 阅读 · 0 评论 -
C语言高级编程:接续符‘\‘的用法
接续符(\)表示断行。1)编译器将反斜杠剔除,跟在反斜杠后面的字符自动接续到前一行2)接续单词(函数名、关键字、变量等)时,反斜杠之后不能有空格,反斜杠下一行之前也不能有空格。如果不是接续单词,如定义函数宏,反斜杠下一行之前可以有空格,但反斜杠之后最好也没有空格,否则编译会产生警告。3)接续符适合在宏定义代码块时使用(不可以不使用,否则编译会报错)测试平台:64位X8...原创 2019-10-08 11:18:00 · 7457 阅读 · 1 评论 -
C语言高级编程:const限定函数形参
1. 代码#include <stdio.h>void fun(const char *p){ *p = 'a';}void main(){ char arr[] = "123"; fun(arr);}2. 编译D:\baoli\Desktopλ gcc test.ctest.c: 在函数‘fun’中:te...原创 2019-10-08 11:13:18 · 1371 阅读 · 0 评论 -
C语言高级编程:i++ 或 ++i作为函数参数
测试机:Ubuntu14.04 x86_641. 代码:#include <stdio.h>void print(int a, int b, int c){ printf("a = %d\n", a); printf("b = %d\n", b); printf("c = %d\n", c);}void main(void){...原创 2019-10-08 11:08:18 · 4676 阅读 · 2 评论 -
C语言高级编程:char、signed char 和 unsigned char的使用区别
1. 区别与联系:1)在定义字符类型时一般使用char来定义2)char被当成有符号或是无符号视不同编译器决定,由于ASCII码范围从0-0x7F(127),所以char无论被当成有符号还是无符号类型均可3)在定义数值类型时使用 signed char 和 unsigned char,signed char表示-128—127,unsigned char表示0—2554)三者在内存...原创 2019-10-08 11:02:13 · 5786 阅读 · 0 评论 -
C语言高级编程:sizeof计算数组大小需要注意的问题
测试平台:64位X86Ubuntu1. 代码:#include <stdio.h>void main(void){ char a[20]; printf("sizeof(a) = %d\n", sizeof(a)); printf("sizeof(&a) = %d\n",sizeof(&a)); printf(...原创 2019-10-08 10:57:41 · 1546 阅读 · 0 评论 -
C语言高级编程系列
关于C语言高级编程系列文章。笔者主要从事Linux kernel、BSP、driver以及TCP/IP方向工作,日常主要使用C语言。工作数年,感叹C语言的简洁却不简单,至今仍不敢说精通C,希望可以通过此系列文章的总结系统地提升自己。更新于:20191124目录:C语言高级编程:预处理中的 # 和 ## C语言高级编程:深入理解const C语言高级编程:数组名赋值给...原创 2019-09-08 11:20:21 · 18100 阅读 · 1 评论 -
C语言高级编程:C语言数据类型大小和取值范围
1. 64位Ubuntu测试结果代码:#include<stdio.h>void main(void){ printf("sizeof(char) = %d\n", sizeof(char)); printf("sizeof(short) = %d\n", sizeof(short)); printf("sizeof(int) = %d\...原创 2019-09-08 10:53:47 · 1361 阅读 · 0 评论 -
C语言高级编程:数组和结构体初始化为0的方法
测试平台:64位X86Ubuntu1. 代码:#include <stdio.h>#include <memory.h>struct st_stu{ char *name; int age; int class;};void main(void){ int a[5] = {0}; //struct ...原创 2019-09-08 10:49:29 · 24782 阅读 · 5 评论 -
C语言高级编程:函数指针的用法
测试平台:64位X86Ubuntu1. 代码:#include <stdio.h>int print(int a){ printf("a = %d\n", a);}void main(void){ int (*pf)(int); int (*pf1)(int); pf = print; pf1 = &p...原创 2019-09-08 10:47:45 · 1613 阅读 · 0 评论 -
C语言高级编程:数组指针与数组
测试平台:64位X86Ubuntu1. 代码:#include <stdio.h>void main(void){ char (*p)[5] = NULL; char (*p1)[5] = NULL; char a[5] = {0,1,2,3,4}; p = a; p1 = &a; print...原创 2019-09-08 10:45:49 · 1013 阅读 · 0 评论 -
C语言高级编程:指针变量p指向的地址与p自身的地址
测试平台:64位X86Ubuntu代码1:#include <stdio.h>void main(void){ int *p; int i = 10; p = &i; printf("&p = %p, p = %p, &i = %p, *p = %d\n", &p, p, &i, *p...原创 2019-09-08 10:41:49 · 2481 阅读 · 0 评论 -
C语言高级编程:预处理中的 # 和 ##
1. 说明#: 字符串化,使用时需加""##:组合2个C语言标识符(token)测试平台:64位X86Ubuntu2. 代码#include <stdio.h>#define TOKEN_PASTER(n) printf("num_"#n"= %d\n",num_##n)int main(void){ int num_1 = 1...原创 2019-09-08 10:35:18 · 5341 阅读 · 0 评论 -
C语言高级编程:利用堆栈溢出修改函数返回地址
利用函数堆栈溢出,修改函数返回地址,进而调用别的函数。测试环境:win10 x86-64gcc: x86_64-pc-cygwin代码#include <stdio.h>#include <stdlib.h>#include <string.h>int len;typedef void ( * p_fun)(vo...原创 2019-08-09 20:52:33 · 3608 阅读 · 5 评论 -
C语言高级编程:大端模式和小端模式(Big-Endian和Little-Endian)
大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。测试平台:64位X86Ubuntu代码:#include<stdio.h>int is_little_endian(){ union ch...原创 2019-08-03 17:00:59 · 2739 阅读 · 3 评论 -
C语言高级编程:深入理解const
const修饰的变量,其实质是告诉程序员或编译器该变量为只读,如果程序员在程序中显示的修改一个只读变量,编译器会毫不留情的给出一个error。而对于像数组溢出,隐式修改等程序不规范书写造成的运行过程中的修改,编译器是无能为力的,也说明const修饰的变量仍然是具备变量属性的。测试平台:64位X86Ubuntu代码1:#include<stdio.h>vo...原创 2019-08-03 16:57:16 · 3625 阅读 · 8 评论 -
C语言高级编程:数组名赋值给指针变量的用法解析
代码:#include<stdio.h>typedef struct test{ int a; int b; int c;} TEST;TEST arr[]={ {1,2,3}, {4,5,6}, {7,8,9}};void main(void){ TEST *tmp; tmp = arr; ...原创 2019-08-03 16:44:17 · 15248 阅读 · 2 评论 -
C语言高级编程:数组地址与指针
#include <stdio.h>void main(){ char a[2][3]; char *b; char c[5]; b=c; printf("addr of arr:\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n%p\n" ,a,a+1,&a,&a+...原创 2019-01-10 20:21:50 · 2234 阅读 · 1 评论 -
C语言高级编程:extern用法
假如一个程序由a.c和b.c组成如果需要在b.c中引用或调用在a.c中定义的变量或函数。1)引用外部变量引用前必须声明:extern int a_tmp;extern不能去掉,int a_tmp; 重复定义了一个变量2)调用外部函数调用前必须声明:extern void a_fun(void);或者:void a_fun(void);...原创 2018-12-01 17:01:24 · 2081 阅读 · 0 评论 -
C语言高级编程:i++与++i区别
Ubuntu版本:ubuntu-gnome-16.04-desktop-amd64,gnome版gcc:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)-----------------------------------------------------------------------------------...原创 2018-12-01 16:52:37 · 5556 阅读 · 6 评论 -
C语言高级编程:二级指针的赋值
测试环境:win10+cygwin---------------------------------在c语言中,经常会对二级指针变量(即指针的指针)进行赋值操作。如果要对一个二级指针进行赋值,不能采用 p = &(&i) 这种语句,即不能对一个变量进行两次取地址操作。因为 &i 的值是一个右值,而&的操作数必须是左值,所以&(&i)会产...原创 2018-09-02 11:51:16 · 11909 阅读 · 0 评论