-----------------------------------------------------------------------------
// main.c// Created by weichen on 15/2/1.// Copyright (c) 2015年 weichen. All rights reserved.#includeint main(int argc, const char * argv[]) { /* 取地址与获取大小: 1. 运算符sizeof可以给出某个类型或变量在内存中的字节数 2. scanf("%d", &a);里面的&为运算符;&用于获取变量的地址,其操作数必须是变量 3. &不能对没有的东西取地址,如:&(a++),&(++a);取地址符右边必须有一个变量 */ int a = 0; int b = (int)&a; //将a的地址强制类型转换为整型 printf("sizeof(a)=%ld\n", sizeof(a)); //4 printf("sizeof(int)=%ld\n", sizeof(int)); //4 //4. double变量在内存中占据的空间是int变量的两倍 //5. 地址的大小是否与int相同取决于编译器,取决于是32位还是64位架构,并不总是相同 printf("sizeof(int)=%ld\n", sizeof(double)); //8 printf("%lu\n", sizeof(&a)); //8(64位架构),32为架构下int和地址都是4个字节 printf("0x%x\n", &a); //0x5fbff82c, %x代表输出十六进制 printf("%p\n", &a); //0x7fff5fbff82c(64位架构下),32位架构下为0x5fbff82c printf("%p\n", b); //0x5fbff82c //5. 相邻地址的差距永远是4 int c[10]; printf("%p\n", &c); //0x7fff5fbff810 printf("%p\n", &c[0]); //0x7fff5fbff810 printf("%p\n", &c[1]); //0x7fff5fbff814 printf("%p\n", c); //0x7fff5fbff810 printf("%p\n", c[0]); //0x0 printf("%p\n", c[1]); //0x0 return 0;}/* 上面有不少带百分号的输出类型,这里做个归纳: %d,读入一个十进制数 decimal %c,读入一个字符 char %a,读入一个指数形式的浮点值 (ONLY C99) %i,读入十进制,八进制,十六进制 incertitude %o,读入八进制整数 octal %x,%X,读入十六进制 hex %s,读入一个字符串,遇空格、制表符或换行符结束 string %f,用来输入实数,可以用小数形式或指数形式输入 float %lf,按双精度输入或输出 longFloat %p,读入一个指针 pointer %u,读入一个无符号十进制整数 unsigned %lu,无符号长整型 longUnsigned %n,至此已读入值的等价字符数 num %[],扫描字符集合 %%,读%符号 */
// main.c// Created by weichen on 15/2/4.// Copyright (c) 2015年 weichen. All rights reserved.#includeint main(void) { /* 指针:保存地址的变量,也就是指针变量的值是其它变量的地址。 1. 变量的值是内存的地址 2. 普通变量的值是实际的值 3. 指针变量的值是具有实际值的变量的地址(意思和1一样) */ /* int i; int *p = &i; 将i的地址给“指针p”(变量的值是内存的地址) int* p,q; *p为int,q为int int *p,q; 同上 int *p,*q; *p为int,*q为int */ /* //指针作为函数参数 void custom(int *p); //调用函数时传入地址, 函数内可通过指针访问变量a, 也可以修改a int a = 0; custom(&a); //如果不将i的地址传入scanf,那么计算机将理解为i的值就是地址,最终运行将报错 scanf("%d", i); */ int i = 6; printf("&i=%p\n", &i); //&i=0x7fff5fbff838 f(&i); //p=0x7fff5fbff838 k(i); //p=6 g(&i); //p=6 m(&i); //p=10 return 0;}int f(int *p) { printf("p=%p\n", p); return 0;}int k(int p) { printf("p=%d\n", p); return 0;}int g(int *p) { printf("p=%d\n", *p); *p = 10; //更改了i的值 return 0;}int m(int *p) { printf("p=%d\n", *p); return 0;}
// main.c// Created by weichen on 15/2/4.// Copyright (c) 2015年 weichen. All rights reserved.#includeint main(void) { /* 指针与数组的关系: 函数参数表中的数组(a[])实际上是指针, 因此也可以写成*a作为参数形式, 但不能使用sizeof得到正确值。 */ int a[] = { 1, 3, 5, 6, 8, 19}; int min,max; printf("main sizeof(a)=%lu\n", sizeof(a)); //main sizeof(a)=24 printf("main a=%p\n", a); //main a=0x7fff5fbff820 minmax(a, sizeof(a)/sizeof(a[0]), &min, &max); printf("a[0]=%d\n", a[0]); //a[0]=1 printf("min=%d, max=%d\n", min, max); int *p = &min; printf("*p=%d\n", *p); //*p=1 printf("p[0]=%d\n", p[0]); //p[0]=1, 对于指针变量,可以采用数组的写法 printf("*a=%d\n", *a); //*a=1 //int b[] <=相当于=> int * const b; return 0;}int minmax(int a[], int len, int *min, int *max) { //注: sizeof an array function parameter will return size of 'int *' instead of 'int []' //作为函数参数的数组大小将返回指针的大小而不是数组的大小 printf("minmax sizeof(a)=%lu\n", sizeof(a));//minmax sizeof(a)=8 , 32位架构下为4 printf("minmax a=%p\n", a); //minmax a=0x7fff5fbff820 *min = *max = a[0]; return 0;}/* 以下四种函数原型(作为参数)是等价的: int sum(int *ar, int n); int sum(int *, int); int sum(int ar[], int n); int sum(int [], int);*//* 数组变量是特殊的指针: int a[10]; int *p = a; //‘数组变量’本身表达地址,无需用&取地址 int b == &a[0]; //但是‘数组单元’表达的是变量,需要用&取地址 []运算符可以对数组做,也可以对指针做 p[0] <=等价=> a[0] 运算符可以对指针做,也可以对数组做 *a = 20; 数组变量是const的常量指针,所以不能被赋值 int a[] <=相当于=> int * const a =*/
// main.c// Created by weichen on 15/2/5.// Copyright (c) 2015年 weichen. All rights reserved.#includeint main(int argc, const char * argv[]) { /* 字符类型char: 1. 用单引号表示的字符字面量,如'a', '1' 2. ''也表示字符 3. printf和scanf里用%0来输入输出字符 */ char c = '1'; //字符1 char d = 1; char c2 = 'a'; //字符a int i; printf("c = %c\n", c); //1 printf("c = %d\n", c); //49 ,以整数形式 printf("c2 = %d\n", c2);//97,代表整数 printf("d = %c\n", d); //空 if(c == d) { printf("c = d\n"); } else { printf("c != d\n"); } printf("==========\n"); /* scanf只能以整数形式输入: 1. 输入49时,%c形式输出1,%d形式输出49 2. '1'的ASCII编码是49,所以当i==49时,它代表'1' */ scanf("%d", &i); printf("i = %c\n", i); printf("i = %d\n", i); if(49 == '1') { printf("right!\n"); } printf("==========\n"); /* 字符计算: 1. 一个字符加一个数字得到ASCII码表中那个数之后的字符 2. 两个字符的减,得到它们在表中的距离 */ char e = 'A'; e++; printf("%c\n", e); //B int f = 'Z' - 'A'; printf("%d\n", f); //25 //字母在ASCII表中是顺序排列的 //大写字母和小写字母是分开排列的,'a'-'A'可以得到两段的距离; //所以把一个大写字母变成小写字母:a+'a'-'A',把一个小写字母变成大写字母:a+'A'-'a'
/*
逃逸字符:
用来表达无法打印出来的控制字符或特殊字符,由一个反斜杠“\”开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符
\b 回退一格(但不删除) //backspace
\t 制表位,每行固定的位置 //tab
\n 换行(由于打字机上换行和回车是两个字符,所以c语言也是将它们分开的) //newline
\r 回车 //return
\" 双引号
\' 单引号
\\ 反斜杠本身
*/
printf("123\b\n456\n");
printf("123\t456\n");
printf("12\t456");
return 0;}
ASCII码表
ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 | ASCII值 | 控制字符 |
0 | NUL | 32 | (space) | 64 | @ | 96 | 、 |
1 | SOH | 33 | ! | 65 | A | 97 | a |
2 | STX | 34 | ” | 66 | B | 98 | b |
3 | ETX | 35 | # | 67 | C | 99 | c |
4 | EOT | 36 | $ | 68 | D | 100 | d |
5 | ENQ | 37 | % | 69 | E | 101 | e |
6 | ACK | 38 | & | 70 | F | 102 | f |
7 | BEL | 39 | ' | 71 | G | 103 | g |
8 | BS | 40 | ( | 72 | H | 104 | h |
9 | HT | 41 | ) | 73 | I | 105 | i |
10 | LF | 42 | * | 74 | J | 106 | j |
11 | VT | 43 | + | 75 | K | 107 | k |
12 | FF | 44 | , | 76 | L | 108 | l |
13 | CR | 45 | - | 77 | M | 109 | m |
14 | SO | 46 | . | 78 | N | 110 | n |
15 | SI | 47 | / | 79 | O | 111 | o |
16 | DLE | 48 | 0 | 80 | P | 112 | p |
17 | DCI | 49 | 1 | 81 | Q | 113 | q |
18 | DC2 | 50 | 2 | 82 | R | 114 | r |
19 | DC3 | 51 | 3 | 83 | X | 115 | s |
20 | DC4 | 52 | 4 | 84 | T | 116 | t |
21 | NAK | 53 | 5 | 85 | U | 117 | u |
22 | SYN | 54 | 6 | 86 | V | 118 | v |
23 | TB | 55 | 7 | 87 | W | 119 | w |
24 | CAN | 56 | 8 | 88 | X | 120 | x |
25 | EM | 57 | 9 | 89 | Y | 121 | y |
26 | SUB | 58 | : | 90 | Z | 122 | z |
27 | ESC | 59 | ; | 91 | [ | 123 | { |
28 | FS | 60 | < | 92 | \ | 124 | | |
29 | GS | 61 | = | 93 | ] | 125 | } |
30 | RS | 62 | > | 94 | ^ | 126 | ~ |
31 | US | 63 | ? | 95 | — | 127 | DEL |
// main.c// Created by weichen on 15/3/3.// Copyright (c) 2015年 weichen. All rights reserved.#includeint main(int argc, const char * argv[]) { /* 字符数组: 非C语言的字符串,不能用字符串的方式做计算 */ char word[] = { 'w', 'o', 'r', 'd', '!'}; //word[0] = 'w'; /* C语言的字符串: 1. 以0(整数0)结尾的一串字符 0或'\0'是一样的(注意整型0代表4个字节,字符串'\0'一定是一个字节);但是和'0'不同,这个一个字符,表达ASCII的0,十进制的48 2. 0标志字符串的结束,但它不是字符串的一部分 计算字符串长度的时候不包含这个0 3. 字符串以数组的形式存在,以数组或指针的形式访问】 更多的是以指针的形式 4. string.h里有很多处理字符串的函数 */ char world[] = { 'w', 'o', 'r', 'l', 'd', '!', '\0'}; //word[6] = '\0'; //字符串变量 char *str = "Hello"; //指针指向字符数组 char hello[] = "Hello"; //字符数组的内容为Hello char line[10] = "Hello"; //字符数组长度10,字符串Hello,占6个字节,包括结尾的0 /* 字符串常量 如:"Hello" "Hello"会被编译器变成一个字符数组放在某处,这个数组的长度是6,结尾还有表示结束的0 两个相邻的字符串常量会被自动连接起来 */ /* 总: C语言的字符串是以字符数组的形态存在的 不能用运算符对字符串做运算 通过数组的方式可以遍历字符串 唯一特殊的地方是字符串字面量可以用来初始化字符数组 标准库提供了一系列字符串函数 */ return 0;}
字符串赋值
char *t = "title";
char *s;
s = t; //没有产生新的字符串,只是让指针s指向了t所指的字符串,对s的任何操作都是对t做的。
//字符串输入输出
char string[8];
scanf("%s", string);
printf("%s", string);
scanf读入一个字符串,到空格、tab或回车为止。
#includeint main(int argc, const char * argv[]) { // 字符串输入输出 char string[8]; char string2[8]; //安全的输入 //在%和s之间的数字表示最多允许读入的字符数量,这个数字应该比数组的大小小一 scanf("%7s", string); //12345678 scanf("%7s", string2); printf("%s##%s##", string, string2); //1234567##8## //常见错误 //char *string; scanf("%s", string); //以为char*是字符串类型,定义了一个字符串类型的变量string就可以直接使用了 //由于没有对string初始化为0,所以不一定每次运行都出错 //这是一个空的字符串 char buffer[100] = ""; //buffer[0] == "\0"; //char buffer[] = ""; //这个数组的长度只有1,buffer[0] == "\0",放不下任何字符串 return 0;}
#include#include int main(int argc, const char * argv[]) { /* 字符串函数:string.h strlen strcmp strcpy strcat strchr strstr */ //size_t strlen(const char *s); //作为参数,数组形式和指针形式是一样的,数组也是指针;返回s的字符串长度,不包括结尾的0 //如果函数不修改参数,应该以常量形式传入 char line[] = "hello"; printf("strlen=%lu\n", strlen(line)); //strlen=5 printf("sizeof=%lu\n", sizeof(line)); //sizeof=6 //int strcmp(const char *s1, const char *s2); //比较两个字符串,返回:0(s1==s2),1(s1>s2),-1(s1
Link:
@黑眼诗人 <www.farwish.com>