【ebay美国 mymalloc】// 单行注释以//开始 。/*多行注释是这个样子的 。*/// 宏定义常数:#define #define DAYS_IN_YEAR 365// 枚举定义常数:enumenum days { SUN = 1, MON, TUE, WED, THU, FRI, SAT };// MON 自动被定义为 2,TUE 被定义为 3,以此类推 。// 用 #include 来导入头文件#include <stdlib.h>#include <stdio.h>#include <string.h>// <尖括号>间的文件名是 C 标准库的头文件 。// 标准库以外的头文件,使用双引号代替尖括号 。#include "my_header.h"// 函数的签名可以事先在 .h 文件中声明,// 也可以直接在 .c 文件的头部定义 。void function_1(char c);void function_2(void);// 如果函数出现在 main() 之后,那么必须在 main() 之前// 先声明一个函数原型int add_two_ints(int x1, int x2); // 函数原型// 你的程序的入口是一个返回值为整型的main函数int main() {// 用printf打印到标准输出,可以设定格式,// %d 代表整数, \n 代表换行printf("%d\n", 0); // => 打印 0// 所有的语句都要以分号结束///////////////////////////////////////// 类型///////////////////////////////////////// 在使用变量之前我们必须先声明它们 。// 变量在声明时需要指明其类型,而类型能够告诉系统这个变量所占用的空间// int型(整型)变量一般占用4个字节int x_int = 0;// short型(短整型)变量一般占用2个字节short x_short = 0;// char型(字符型)变量会占用1个字节char x_char = 0;char y_char = \'y\'; // 字符变量的字面值需要用单引号包住// long型(长整型)一般需要4个字节到8个字节; 而long long型则至少需要8个字节(64位)long x_long = 0;long long x_long_long = 0; // float一般是用32位表示的浮点数字float x_float = 0.0;// double一般是用64位表示的浮点数字double x_double = 0.0;// 整数类型也可以有无符号的类型表示 。这样这些变量就无法表示负数// 但是无符号整数所能表示的范围就可以比原来的整数大一些unsigned short ux_short;unsigned int ux_int;unsigned long long ux_long_long;// 单引号内的字符是机器的字符集中的整数 。\'0\' // => 在ASCII字符集中是48\'A\' // => 在ASCII字符集中是65// char类型一定会占用1个字节,但是其他的类型却会因具体机器的不同而各异// sizeof(T) 可以返回T类型在运行的机器上占用多少个字节 // 这样你的代码就可以在各处正确运行了// sizeof(obj)返回表达式(变量、字面量等)的尺寸printf("%zu\n", sizeof(int)); // => 4 (大多数的机器字长为4)// 如果`sizeof`的参数是一个表达式,那么这个参数不会被演算(VLA例外,见下)// 它产生的值是编译期的常数int a = 1;// size_t是一个无符号整型,表示对象的尺寸,至少2个字节size_t size = sizeof(a++); // a++ 不会被演算printf("sizeof(a++) = %zu where a = %d\n", size, a);// 打印 "sizeof(a++) = 4 where a = 1" (在32位架构上)// 数组必须要被初始化为具体的长度char my_char_array[20]; // 这个数组占据 1 * 20 = 20 个字节int my_int_array[20]; // 这个数组占据 4 * 20 = 80 个字节// (这里我们假设字长为4)// 可以用下面的方法把数组初始化为0:char my_array[20] = {0};// 索引数组和其他语言类似 -- 好吧,其实是其他的语言像Cmy_array[0]; // => 0// 数组是可变的,其实就是内存的映射!my_array[1] = 2;printf("%d\n", my_array[1]); // => 2// 在C99 (C11中是可选特性),变长数组(VLA)也可以声明长度 。// 其长度不用是编译期常量 。printf("Enter the array size: "); // 询问用户数组长度char buf[0x100];fgets(buf, sizeof buf, stdin);// stroul 将字符串解析为无符号整数size_t size = strtoul(buf, NULL, 10);int var_length_array[size]; // 声明VLAprintf("sizeof array = %zu\n", sizeof var_length_array);// 上述程序可能的输出为:// > Enter the array size: 10// > sizeof array = 40// 字符串就是以 NUL (0x00) 这个字符结尾的字符数组,// NUL可以用\'\0\'来表示.// (在字符串字面量中我们不必输入这个字符,编译器会自动添加的)char a_string[20] = "This is a string";printf("%s\n", a_string); // %s 可以对字符串进行格式化/*也许你会注意到 a_string 实际上只有16个字节长.第17个字节是一个空字符(NUL) 而第18, 19 和 20 个字符的值是未定义 。*/printf("%d\n", a_string[16]); // => 0//byte #17值为0(18,19,20同样为0)// 单引号间的字符是字符字面量// 它的类型是`int`,而 *不是* `char`// (由于历史原因)int cha = \'a\'; // 合法char chb = \'a\'; // 同样合法 (隐式类型转换// 多维数组int multi_array[2][5] = {{1, 2, 3, 4, 5},{6, 7, 8, 9, 0}}// 获取元素int array_int = multi_array[0][2]; // => 3///////////////////////////////////////// 操作符///////////////////////////////////////// 多个变量声明的简写int i1 = 1, i2 = 2;float f1 = 1.0, f2 = 2.0;int a, b, c;a = b = c = 0;// 算数运算直截了当i1 + i2; // => 3i2 - i1; // => 1i2 * i1; // => 2i1 / i2; // => 0 (0.5,但会被化整为 0)f1 / f2; // => 0.5, 也许会有很小的误差// 浮点数和浮点数运算都是近似值// 取余运算11 % 3; // => 2// 你多半会觉得比较操作符很熟悉, 不过C中没有布尔类型// 而是用整形替代// (C99中有_Bool或bool 。)// 0为假, 其他均为真. (比较操作符的返回值总是返回0或1)3 == 2; // => 0 (false)3 != 2; // => 1 (true)3 > 2; // => 13 < 2; // => 02 <= 2; // => 12 >= 2; // => 1// C不是Python —— 连续比较不合法int a = 1;// 错误int between_0_and_2 = 0 < a < 2;// 正确int between_0_and_2 = 0 < a && a < 2;// 逻辑运算符适用于整数!3; // => 0 (非)!0; // => 11 && 1; // => 1 (且)0 && 1; // => 00 || 1; // => 1 (或)0 || 0; // => 0// 条件表达式 ( ? : )int a = 5;int b = 10;int z;z = (a > b) ? a : b; //10 “若a > b返回a,否则返回b 。”// 增、减char *s = "iLoveC"int j = 0;s[j++]; // "i" 返回s的第j项,然后增加j的值 。j = 0;s[++j]; // => "L"增加j的值,然后返回s的第j项 。// j-- 和 --j 同理// 位运算~0x0F; // => 0xF0 (取反)0x0F & 0xF0; // => 0x00 (和)0x0F | 0xF0; // => 0xFF (或)0x04 ^ 0x0F; // => 0x0B (异或)0x01 << 1; // => 0x02 (左移1位)0x02 >> 1; // => 0x01 (右移1位)// 对有符号整数进行移位操作要小心 —— 以下未定义:// 有符号整数位移至符号位 int a = 1 << 32// 负数左移位 int a = -1 << 2// 移位超过或等于该类型数值的长度// int a = 1 << 32; // 假定int32位///////////////////////////////////////// 控制结构///////////////////////////////////////if (0) {printf("I am never run\n");} else if (0) {printf("I am also never run\n");} else {printf("I print\n");}// While循环int ii = 0;while (ii < 10) { // 任何非0的值均为真printf("%d, ", ii++); // ii++ 在取值过后自增} // =>打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "printf("\n");int kk = 0;do {printf("%d, ", kk);} while (++kk < 10); // ++kk 先自增,再被取值// => 打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "printf("\n");// For 循环int jj;for (jj=0; jj < 10; jj++) {printf("%d, ", jj);} // => 打印 "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "printf("\n");// *****注意*****:// 循环和函数必须有主体部分,如果不需要主体部分:int i;for (i = 0; i <= 5; i++) {; // 使用分号表达主体(null语句)}// 多重分支:switch()switch (some_integral_expression) {case 0: // 标签必须是整数常量表达式do_stuff();break; // 如果不使用break,控制结构会继续执行下面的标签case 1:do_something_else();break;default:// 假设 `some_integral_expression` 不匹配任何标签fputs("error!\n", stderr);exit(-1);break;}///////////////////////////////////////// 类型转换///////////////////////////////////////// 在C中每个变量都有类型,你可以将变量的类型进行转换// (有一定限制)int x_hex = 0x01; // 可以用16进制字面量赋值// 在类型转换时,数字本身的值会被保留下来printf("%d\n", x_hex); // => 打印 1printf("%d\n", (short) x_hex); // => 打印 1printf("%d\n", (char) x_hex); // => 打印 1// 类型转换时可能会造成溢出,而且不会抛出警告printf("%d\n", (char) 257); // => 1 (char的最大值为255,假定char为8位长)// 使用<limits.h>提供的CHAR_MAX、SCHAR_MAX和UCHAR_MAX宏可以确定`char`、`signed_char`和`unisigned char`的最大值 。// 整数型和浮点型可以互相转换printf("%f\n", (float)100); // %f 格式化单精度浮点printf("%lf\n", (double)100); // %lf 格式化双精度浮点printf("%d\n", (char)100.0);///////////////////////////////////////// 指针///////////////////////////////////////// 指针变量是用来储存内存地址的变量// 指针变量的声明也会告诉它所指向的数据的类型// 你可以使用得到你的变量的地址,并把它们搞乱,;-)int x = 0;printf("%p\n", &x); // 用 & 来获取变量的地址// (%p 格式化一个类型为 void *的指针)// => 打印某个内存地址// 指针类型在声明中以*开头int* px, not_a_pointer; // px是一个指向int型的指针px = &x; // 把x的地址保存到px中printf("%p\n", (void *)px); // => 输出内存中的某个地址printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer));// => 在64位系统上打印“8,4” 。// 要得到某个指针指向的内容的值,可以在指针前加一个*来取得(取消引用)// 注意: 是的,这可能让人困惑,\'*\'在用来声明一个指针的同时取消引用它 。printf("%d\n", *px); // => 输出 0, 即x的值// 你也可以改变指针所指向的值// 此时你需要取消引用上添加括号,因为++比*的优先级更高(*px)++; // 把px所指向的值增加1printf("%d\n", *px); // => 输出 1printf("%d\n", x); // => 输出 1// 数组是分配一系列连续空间的常用方式int x_array[20];int xx;for (xx=0; xx<20; xx++) {x_array[xx] = 20 - xx;} // 初始化 x_array 为 20, 19, 18,... 2, 1// 声明一个整型的指针,并初始化为指向x_arrayint* x_ptr = x_array;// x_ptr现在指向了数组的第一个元素(即整数20). // 这是因为数组通常衰减为指向它们的第一个元素的指针 。// 例如,当一个数组被传递给一个函数或者绑定到一个指针时,//它衰减为(隐式转化为)一个指针 。// 例外: 当数组是`&`操作符的参数:int arr[10];int (*ptr_to_arr)[10] = &arr; // &arr的类型不是`int *`!// 它的类型是指向数组的指针(数组由10个int组成)// 或者当数组是字符串字面量(初始化字符数组)char arr[] = "foobarbazquirk";// 或者当它是`sizeof`或`alignof`操作符的参数时:int arr[10];int *ptr = arr; // 等价于 int *ptr = &arr[0];printf("%zu, %zu\n", sizeof arr, sizeof ptr); // 应该会输出"40, 4"或"40, 8"// 指针的增减多少是依据它本身的类型而定的// (这被称为指针算术)printf("%d\n", *(x_ptr + 1)); // => 打印 19printf("%d\n", x_array[1]); // => 打印 19// 你也可以通过标准库函数malloc来实现动态分配// 这个函数接受一个代表容量的参数,参数类型为`size_t`// 系统一般会从堆区分配指定容量字节大小的空间// (在一些系统,例如嵌入式系统中这点不一定成立// C标准对此未置一词 。)int *my_ptr = malloc(sizeof(*my_ptr) * 20);for (xx=0; xx<20; xx++) {*(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx} // 初始化内存为 20, 19, 18, 17... 2, 1 (类型为int)// 对未分配的内存进行取消引用会产生未定义的结果printf("%d\n", *(my_ptr + 21)); // => 谁知道会输出什么// malloc分配的区域需要手动释放// 否则没人能够再次使用这块内存,直到程序结束为止free(my_ptr);// 字符串通常是字符数组,但是经常用字符指针表示// (它是指向数组的第一个元素的指针)// 一个优良的实践是使用`const char *`来引用一个字符串字面量,// 因为字符串字面量不应当被修改(即"foo"[0] = \'a\'犯了大忌)const char* my_str = "This is my very own string";printf("%c\n", *my_str); // => \'T\'// 如果字符串是数组,(多半是用字符串字面量初始化的)// 情况就不一样了,字符串位于可写的内存中char foo[] = "foo";foo[0] = \'a\'; // 这是合法的,foo现在包含"aoo"function_1();} // main函数结束///////////////////////////////////////// 函数///////////////////////////////////////// 函数声明语法:// <返回值类型> <函数名称>(<参数>)int add_two_ints(int x1, int x2){return x1 + x2; // 用return来返回一个值}/*函数是按值传递的 。当调用一个函数的时候,传递给函数的参数是原有参数的拷贝(数组除外) 。你在函数内对参数所进行的操作不会改变该参数原有的值 。但是你可以通过指针来传递引用,这样函数就可以更改值例子:字符串本身翻转*/// 类型为void的函数没有返回值void str_reverse(char *str_in){char tmp;int ii = 0;size_t len = strlen(str_in); // `strlen()`` 是C标准库函数for(ii = 0; ii < len / 2; ii++){tmp = str_in[ii];str_in[ii] = str_in[len - ii - 1]; // 从倒数第ii个开始str_in[len - ii - 1] = tmp;}}/*char c[] = "This is a test.";str_reverse(c);printf("%s\n", c); // => ".tset a si sihT"*/// 如果引用函数之外的变量,必须使用extern关键字int i = 0;void testFunc() {extern int i; // 使用外部变量 i}// 使用static确保external变量为源文件私有static int i = 0; // 其他使用 testFunc()的文件无法访问变量ivoid testFunc() {extern int i;}//**你同样可以声明函数为static**///////////////////////////////////////// 用户自定义类型和结构///////////////////////////////////////// Typedefs可以创建类型别名typedef int my_type;my_type my_type_var = 0;// struct是数据的集合,成员依序分配,按照// 编写的顺序struct rectangle {int width;int height;};// 一般而言,以下断言不成立:// sizeof(struct rectangle) == sizeof(int) + sizeof(int)//这是因为structure成员之间可能存在潜在的间隙(为了对齐)[1]void function_1(){struct rectangle my_rec;// 通过 . 来访问结构中的数据my_rec.width = 10;my_rec.height = 20;// 你也可以声明指向结构体的指针struct rectangle *my_rec_ptr = &my_rec;// 通过取消引用来改变结构体的成员...(*my_rec_ptr).width = 30;// ... 或者用 -> 操作符作为简写提高可读性my_rec_ptr->height = 10; // Same as (*my_rec_ptr).height = 10;}// 你也可以用typedef来给一个结构体起一个别名typedef struct rectangle rect;int area(rect r){return r.width * r.height;}// 如果struct较大,你可以通过指针传递,避免// 复制整个struct 。int area(const rect *r){return r->width * r->height;}///////////////////////////////////////// 函数指针////////////////////////////////////////*在运行时,函数本身也被存放到某块内存区域当中函数指针就像其他指针一样(不过是存储一个内存地址) 但却可以被用来直接调用函数,并且可以四处传递回调函数但是,定义的语法初看令人有些迷惑例子:通过指针调用str_reverse*/void str_reverse_through_pointer(char *str_in) {// 定义一个函数指针 f.void (*f)(char *); // 签名一定要与目标函数相同f = &str_reverse; // 将函数的地址在运行时赋给指针(*f)(str_in); // 通过指针调用函数// f(str_in); // 等价于这种调用方式}/*只要函数签名是正确的,任何时候都能将任何函数赋给某个函数指针为了可读性和简洁性,函数指针经常和typedef搭配使用:*/typedef void (*my_fnp_type)(char *);// 实际声明函数指针会这么用:// ...// my_fnp_type f; // 特殊字符\'\a\' // bell\'\n\' // 换行\'\t\' // tab\'\v\' // vertical tab\'\f\' // formfeed\'\r\' // 回车\'\b\' // 退格\'\0\' // null,通常置于字符串的最后 。//hello\n\0. 按照惯例,\0用于标记字符串的末尾 。\'\\\' // 反斜杠\'\?\' // 问号\'\\'\' // 单引号\'\"\' // 双引号\'\xhh\' // 十六进制数字. 例子: \'\xb\' = vertical tab\'\ooo\' // 八进制数字. 例子: \'\013\' = vertical tab// 打印格式:"%d"// 整数"%3d"// 3位以上整数 (右对齐文本)"%s"// 字符串"%f"// float"%ld"// long"%3.2f" // 左3位以上、右2位以上十进制浮"%7.4s" // (字符串同样适用)"%c"// 字母"%p"// 指针"%x"// 十六进制"%o"// 八进制"%%"// 打印 %///////////////////////////////////////// 演算优先级/////////////////////////////////////////---------------------------------------------------////操作符| 组合////---------------------------------------------------//// () [] -> .| 从左到右//// ! ~ ++ -- + = *(type)sizeof| 从右到左//// * / %| 从左到右//// + -| 从左到右//// << >>| 从左到右//// < <= > >=| 从左到右//// == !=| 从左到右//// &| 从左到右//// ^| 从左到右//// || 从左到右//// &&| 从左到右//// ||| 从左到右//// ?:| 从右到左//// = += -= *= /= %= &= ^= |= <<= >>= | 从右到左//// ,| 从左到右////---------------------------------------------------//
- 哈利波特几个学院介绍 哈利波特学院介绍图片
- 美国年轻人参军入伍到底图什么?
- 中国女排大逆转美国队,朱婷贡献25分,荣膺得分王,如何评价朱婷的表现?
- 如果英国人当年迁都美国,大英帝国时代就可以延续下去,你怎么看呢?
- 中东难民潮主要是美国侵略造成的,为什么美国不承担责任?
- 美国绿卡多久能拿到 如何获得美国绿卡
- 美国最杰出的六位总统是谁叫什么名字 美国最杰出的六位总统
- 美国在役军人多少人 中国在役军人多少
- 伊朗重金悬赏刺杀特朗普,如果特朗普遇害美国将会怎样报复伊朗?
- 完美国际2辅助工具 完美国际sf外挂
特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
