【C语言深度分析】
玛丽奥ZJY
这个作者很懒,什么都没留下…
展开
-
【C深入】Const常量与指针
#include <stdio.h>int main(){ int i = 0; const int* p = &i; *p = 5; return 0;}右指:不变#include <stdio.h>int main(){ int i = 0; int...原创 2018-06-28 16:56:39 · 138 阅读 · 0 评论 -
【C深入】数组参数和指针参数分析
传递与访问二维数组的方式:#include <stdio.h>void access(int a[][3], int row){ int col = sizeof(*a) / sizeof(int); int i = 0; int j = 0; printf("sizeof(a) = %d\n", sizeof(a)); ...原创 2018-07-02 13:46:21 · 212 阅读 · 0 评论 -
【C深入】多维数组和多维指针
指向指针的指针:多级指针的分析与使用(重置动态空间的大小)#include <stdio.h>#include <malloc.h>int reset(char** s,int a_size,int new_size){ char *pp = *s; int len = 0; char *bt = NULL; ...原创 2018-07-02 10:20:47 · 1956 阅读 · 0 评论 -
【C深入】指针数组和数组指针分析
#include <stdio.h>typedef int(AINT5)[5];typedef float(AFLOAT10)[10];typedef char(ACHAR9)[9];int main(){ AINT5 a1; float fArray[10]; AFLOAT10* pf = &fArray; ACHAR9 cArr...原创 2018-06-29 15:40:32 · 151 阅读 · 0 评论 -
【C深入】C语言中的字符串
char *s3 = "hello"; 变量在只读数存储区中上面图片中的第二个程序总是满足条件使用一条语句计算字符串的长度:(使用了逗号表达式和3目表达式)#include <stdio.h>#include <assert.h>int mystrlen(const char* s){ return (assert(s),(*s ? (mystrlen...原创 2018-06-29 14:39:24 · 1252 阅读 · 0 评论 -
【C深入】指针与数组的关系
#include <stdio.h>int main(){ int i; int* pI; char* pC; float* pF; pI = &i; printf("%0X, %0X, %d\n", pI, &i, i); printf("%d, %d, %0X\n", sizeof(i...原创 2018-06-29 12:08:56 · 242 阅读 · 0 评论 -
【C深入】数组基础
编译器只给这20字节空间取了一个名字a,数组的每一个元素都没有名字。数组大小:数组在一片连续的内存空间中存储元素数组元素的个数可以显示或隐式指定int a[5] = {1,2}; //显示数组大小sizeof(a) = 20, 数组长度 sizeof(a)/sizeof(*a) = 5 ,指定数组长度,不管初始化列表有多少个元素,都会以指定的长度来作为唯一的指标分配数组的内存空间如果初始化列表...转载 2018-07-06 17:05:19 · 184 阅读 · 0 评论 -
【C深入】指针基础
#include <stdio.h>int main(){ int i = 5; int* p = &i; printf("%d, %08X\n", i, p); *p = 10; //等价于i = 10; printf("%d, %08X\n", i, p); return 0;}运行输出:i的值变了,...转载 2018-07-06 17:05:30 · 183 阅读 · 0 评论 -
【C深入】#和##运算符使用解析
#include <stdio.h>#define CONVERS(x) #xint main(){ printf("%s\n", CONVERS(Hello world!)); printf("%s\n", CONVERS(100)); printf("%s\n", CONVERS(while)); printf("%s\n", C...原创 2018-06-28 16:44:59 · 237 阅读 · 0 评论 -
【C深入】函数与指针分析
函数类型函数指针: #include <stdio.h>typedef int(FUNC)(int);int test(int i){ return i * i;}void f(){ printf("Call f()...\n");}int main(){ FUNC* pt = test; void(*pf)()...转载 2018-07-02 14:33:43 · 136 阅读 · 0 评论 -
【C深入】动态内存分配
#include <stdio.h>#include <malloc.h>int main(){ int i = 0; int* pI = (int*)malloc(5 * sizeof(int)); short* pS = (short*)calloc(5, sizeof(short)); for(i=0; i<5;...原创 2018-07-02 16:25:07 · 151 阅读 · 0 评论 -
【C深入】优先级
易错的优先级typedef struct _demo{ int* pInt; float f;} Demo;int func(int v, int m){ return (v & m != 0); //优先级!=高于&,应改为return ((v & m) != 0); }int main(){ Demo* pD = (Demo*...原创 2018-06-27 21:52:33 · 536 阅读 · 0 评论 -
【C深入】auto,register,static分析
C语言中的变量可以有自己的属性在定义变量的时候可以加上“属性”关键字“属性”关键字指明变量的特有意义auto即C语言中局部变量的默认属性,并且只能修饰局部变量;编译器默认所有的局部变量都是auto的;auto指明申明的变量在程序的栈上分配空间的static指明变量的“静态”属性;static同时具有“作用域限定符”的意义;static另一意义是文件作用域标示符;static修饰的全局变量,即静态全...转载 2018-07-04 09:37:22 · 192 阅读 · 0 评论 -
【C深入】函数设计技巧(C语言)
函数设计技巧1,不要在函数中使用全局变量,尽量让函数从意义上是一个独立的功能模块 2,参数名要能够体现参数的意义void str_copy (char *str1, char *str2);void str_copy (char *str_dest, char *str_src); 2,如果参数是指针,且仅作输入参数用,则应在类型前加const,以防止该指针在函数体内被意外修改void str_c...转载 2018-07-03 13:46:46 · 395 阅读 · 0 评论 -
【C深入】可变参数分析
C语言中可以定义参数可变的函数,可以增加可以减少,如:printf()参数可变函数的实现依赖于stdarg.h头文件va_list 变量与 va_start,va_end 和 va_arg 配合使用能够访问参数值VA_LIST的用法: (1)首先在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针; (2)然后用VA_START宏初始化变量刚定义的VA_LIST变量; (3)然后用VA...原创 2018-07-03 11:59:11 · 158 阅读 · 0 评论 -
【C深入】认清函数的真面目
函数的由来与好处——以下摘自陈正冲《C语言深度剖析》其实在汇编语言阶段,函数这个概念还是比较模糊的。汇编语言的代码往往就是从入口开始一条一条执行,直到遇到跳转指令(比如ARM 指令B 、BL 、BX 、BLX 之类)然后才跳转到目的指令处执行。这个时候所有的代码仅仅是按其将要执行的顺序排列而已。后来人们发现这样写代码非常费劲,容易出错,也不方便。于是想出一个办法,把一些功能相对来说能成为一个整体的...转载 2018-07-03 11:31:35 · 165 阅读 · 0 评论 -
【C深入】野指针和内存操作分析
初始野指针野指针通常是因为指针变量中保存的值不是一个合法的内存地址而造成的。合法的内存地址:1.堆空间申请的动态空间 2.栈空间上的局部变量所占用的空间野指针不是NULL指针,是指不可用内存的指针NULL指针不容易出错,因为if语句很好判断一个指针是不是NULLC语言没有任何手段可以判断一个指针为野指针!野指针的由来1.局部指针没有被初始化struct Student{ char* n...原创 2018-07-03 09:26:27 · 209 阅读 · 0 评论 -
【C深入】程序中的三国天下,栈,堆,静态内存
1 栈1.1 程序中的栈栈是现代计算机程序里最重要的概念之一。栈在程序中用于维护函数调用上下文。函数中的参数和局部变量存储在栈上。栈是一种后进先出的行为。1.2 函数调用过程栈保存了一个函数调用所需的维护信息:参数、返回地址、局部变量、调用上下文、……每次函数调用都对应着一个栈上的活动记录。调用函数的活动记录位于栈的中部。被调函数的活动记录位于栈的顶部。函数调用栈变化这里返回地址描述应该是有问题,...转载 2018-07-02 17:29:46 · 157 阅读 · 0 评论 -
【C深入】指针阅读技巧解析
现在很多IT公司都会有一些关于复杂声明的面试题,那么我们应该怎么解决这个问题呢?可以利用右左法则。这是一个简单的法则,但可以让我们准确理解所有的声明。 The right-left rule:Start reading the declaration from the innermost parentheses, go right, and then go left. When you enco...转载 2018-07-02 14:48:43 · 194 阅读 · 0 评论 -
【C深入】22_#pragma使用分析【重点】
#pragma是编译器指示字,用于指示编译器完成一些特定的动作#pragma所定义的很多指示字是编译器和操作系统特有的#pragma在不同的编译器间是不可移植的预处理器将忽略它不认识的#pragma指令,当预处理器看到#pragma后,就不会像处理#define,#include那样来进行进一步的处理,会把#pragma指令留给后续的编译模块,编译模块会根据他的参数执行一系列的动作,编译模块如果发...转载 2018-07-06 17:05:26 · 169 阅读 · 0 评论 -
【C 深入】21_#error、#warning和#line
define没有作用域的限制#include <stdio.h>int f1(int a, int b){ #define _MIN_(a,b) ((a)<(b) ? a : b) return _MIN_(a, b);}int f2(int a, int b, int c){ return _MIN_(_MIN_(a,b), c)...原创 2018-06-28 11:55:34 · 849 阅读 · 0 评论 -
【C深入】20_宏定义与使用分析
宏定义常量:#define宏定义常量可以出现在代码的任何地方#define从本行开始,之后的代码都可以使用这个宏常量以上宏定义都正确最后一个宏定义采用了接续符“\”,等同于#define PATH_3 D:\Delphi\CTopic3.ppt宏定义表达式#define表达式有函数调用的假象,却不是函数#define表达式可以比函数更强大#define表达式比函数更容易出错例1:#define ...转载 2018-07-05 16:42:38 · 315 阅读 · 0 评论 -
【C深入】9_const和volatile分析
constconst 修饰的是只读变量,不是常量,会在内存中占用空间,本质上const只对编译器有用,在运行时无用const 修饰的只读变量不能作为左值直接赋值,但可以通知指针修改其值const 修饰的只读变量必须在定义的同时初始化case语句后面不可以跟const修饰的只读变量,case后面只能是整形或者字符型的常量或常量表达式const修饰的数组是只读的,const修饰的数组空间不可以被改变 ...转载 2018-07-03 14:18:16 · 150 阅读 · 0 评论 -
【C深入】8_goto,void,extern,sizeof分析
goto:禁用voidvoid:不允许定义void类型变量,但可以有void类型指针。void*:void* p指针可以接受任意类型指针,作为右值要赋值给左值类型指针必须强制类型转换,如 void* p1; int* p2; p1 = p2; //对, p2 = p1; //错,改为p2 = (int*)p1函数参数可以是任意类型指针,那么气参数应为void*,如:void* m...转载 2018-07-03 14:19:58 · 258 阅读 · 0 评论 -
【C深入】7_循环语句
关键词:循环语句分析、do...while循环、while循环、for循环1. 循环语句分析循环语句的基本工作方式 通过条件表达式判定是否执行循环体 条件表达式遵循if语句表达式原则do,while,for的区别 do语句先执行后判断,循环体至少执行一次 while语句先判断后执行,循环体可能不执行 for语句先判断后执行,相比while更简洁2. do...while循环3. while循环4....转载 2018-07-05 16:42:12 · 141 阅读 · 0 评论 -
【C深入】6_分支语句
关键字:if语句分析、 switch语句分析1. if语句分析if语句用于根据条件选择执行语句else不能独立存在且总是与它最近的if向匹配else语句后可以接连其它if语句 if( condition ){ // statement 1}else{ // statement 2}12345678if语句中零值比较的注意点 1)bool型变量应该出现于条件中,不需要进行比较boo...转载 2018-07-05 16:42:07 · 130 阅读 · 0 评论 -
【C深入】4_类型转换
关键词:类型之间的转换、强制类型转换、隐式类型转换1. 类型之间的转换C语言中的数据类型可以进行转换,转换方式有: 强制类型转换 隐式类型转换2. 强制类型转换强制类型转换的语法: (Type) var_name; (Type) value; 强制类型转换的结果: 目标类型能够容纳目标值:结果不变 目标类型不能容纳目标值:结果将产生截断 注意:不是所有的强制类型转换都能成功,当不能进行强制类型转换...转载 2018-07-04 09:50:28 · 160 阅读 · 0 评论 -
【C深入】3_浮点数的秘密
关键词:内存中的浮点数、浮点数存储示例、十进制浮点数的内存表示、 float类型的不精确示例1. 内存中的浮点数浮点数在内存的存储方式为:S=M*2^N主要由三部分构成:符号位+指数(N)+尾数(M)。类型符号位指数尾数float1位(第31位)8位(第23-30位)23位(第0-22位)double1位(第63位)11位(第52-62位)52位(第0-51位)float和double类型的数据在...转载 2018-07-04 09:46:56 · 351 阅读 · 0 评论 -
【C深入】2_有符号和无符号
关键词:计算机中的符号位、有符号数的表示法、无符号数的表示法、signed和unsigned、无符号数和有符号数的混合运算、错误使用unsigned的后果1. 计算机中的符号位数据类型的最高位用于识别数据的符号 * 最高位为1,表明这个数为负数 * 最高位为0,表明这个数为正数#include <stdio.h>int main(){ char c = -5; s...转载 2018-07-04 09:44:22 · 162 阅读 · 0 评论 -
【C深入】10_struct和union分析
struct空结构体大小,依据编译器的不同而不同,gcc中为0,且不同的结构体变量地址相同;而在g++中为1,不同的结构体变量地址也不同。没有谁对谁错,现代编译器中认为空结构体大小为1较为合理。柔性数组即数组大小待定的数组。规则:结构中最后一个元素允许是未知大小的数组; 结构中的柔性数组成员前面必须至少一个其他成员。typedef struct flex{int len;int arra...转载 2018-07-03 14:11:10 · 124 阅读 · 0 评论 -
【C深入】11_enum和typedef分析
enum是一种自定义类型,真真正正的常量enum默认常量在前一个值的基础上依次加1enum类型的变量只能取定义时的离散值,只能是int型enum类型变量只能取值为花括号内的任何一个值enum color{ GREEN, RED = 2, BLUE};enum变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋初值的那个常量开始依次加1,如果都没有赋值,它们的值从0开始依次递增1。所...转载 2018-07-03 14:01:39 · 225 阅读 · 0 评论 -
【C深入】19_编译过程简介
被隐藏的过程预编译:处理所有的注释,以空格代替将所有的#define删除删除 ,并且展开所有的宏定义处理条件编译指令#if, #ifdef, #elif, #else, #endif 处理#include ,展开被包含的文件保留编译器需要使用的#pragma指令指令预处理指令:编译:对预处理文件进行一系列词法分析 ,语法分析和语义分析词法分析主要分析关键字 ,标示符,标示符 ,立即数等是否合法语法...转载 2018-07-04 09:37:30 · 140 阅读 · 0 评论 -
【C深入】18_三目运算符和逗号表达式
关键词:三目运算符、 三目运算符(a?b:c) 的返回类型、逗号表达式、一行代码实现strlen1. 三目运算符三目运算符(a?b:c) 可作为逻辑运算的载体:当a的值为真时,返回b的值;否则返回c的值#include <stdio.h>int main(){ int a = 1; int b = 2; int c = 0; c = (a <...转载 2018-07-05 16:42:33 · 226 阅读 · 0 评论 -
【C深入】17_++、--操作使用分析
int i = 3;(++i) + (++i) + (++i)表达式的值为多少?15 吗?16 吗?18 吗?对于这种情况,C语言标准并没有作出规定。有的编译器计算出来为18,因为i 经过3 次自加后变为6,然后3 个6 相加得18; 而有的编译器计算出来为16(比如Visual C++6.0,gcc,g++ ),先计算前两个i 的和,这时候i自加两次,2 个i 的和为10,然后再加上第三次自加的...转载 2018-07-04 09:37:36 · 189 阅读 · 0 评论 -
【C深入】16_位运算符分析
注意按位运算符|和&与逻辑运算符||和&&完全是两码事,别混淆了。结合律:a&b&c <=> (a&b)&c <=> a&(B&c)交换律:a&b <=> b&a 左移和右移左移运算符“<<”是双目运算符。其功能把“转载 2018-07-03 14:06:34 · 190 阅读 · 0 评论 -
【C深入】15_逻辑运算符&&、||、!使用分析
int i = 0;int j = 0; if( ++i > 0 || ++j > 0 ){ printf("%d\n", i); //输出1 printf("%d\n", j); //输出0}改为if( ++i > 0 && ++j > 0 ){ printf("%d\n", i); //输出1 pr..转载 2018-07-03 14:27:29 · 608 阅读 · 0 评论 -
【C深入】14_单引号和双引号
char* p1 = 1 ;char* p2 = '1'; ‘1’的ASCII码值为49char* p3 = "1“;0和49地址处为操作系统使用,故访问这些地址如printf("%s, %s, %s", p1, p2, p3)会产生段错误。printf('\n') \n的ASCII码值为10,同理,段错误。'a'表示字符常量,在内存中占1个字节,'a'+1表示'a'的ASCII码加1,结果...转载 2018-07-05 16:42:28 · 154 阅读 · 0 评论 -
【C深入】13_接续符和转义符
以反斜杠(\)表示断行。编译器会将反斜杠剔除掉,跟在反斜杠后面的字符自动接续到前一行。注意:反斜杠之后不能有空格,反斜杠的下一行之前也不能有空格。例://这是一条合法的\ 单行注释 -->//这是一条合法的单行注释/\ /这是一条合法的单行注释 -->//这是一条合法的单行注释#def\ ine MAC\ RO 这是一条合法的\ -->#def...转载 2018-07-05 16:42:22 · 168 阅读 · 0 评论 -
【C深入】12_注释符号
1.int/*...*/i;正确,编译器会在编译过程删除注释,但不是简单的删除而是用空格代替2.char* s = "abcdefgh //hijklmn";正确,编译器认为双引号括起来的内容都是字符串,双斜杠也不例外3.//Is it a \ valid comment? 这是一条合法的注释,因为\是一个接续符4.in/*...*/t i; 错误,注释会被空格替换注:/*…*/形式的注...转载 2018-07-05 16:42:17 · 210 阅读 · 0 评论 -
【C深入】1_基本数据类型分析
数据类型:数据类型可以理解为固定内存大小的别名数据类型是创建变量的模子数据类型的本质:内存大小的别名char代表1个字节,他就是1个字节的别名;short代表2个字节,他就是2个字节的别名;int代表4个字节,他就是4个字节的别名;......当需要1个字节时,把char这个模子拿到内存里一“咔”,1个字节内存就出来就可以使用了;当需要2个字节时,把short这个模子拿到内存里一“咔”,2个字节内...转载 2018-07-04 09:37:14 · 144 阅读 · 0 评论