-----------------------------------------------------------------------------
// main.c
// Created by weichen on 15/2/1.
// Copyright (c) 2015年 weichen. All rights reserved.
#include <stdio.h>
int 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.
#include <stdio.h>
int 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.
#include <stdio.h>
int 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.
#include <stdio.h>
int 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.
#include <stdio.h>
int 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或回车为止。
#include <stdio.h>
int 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 <stdio.h>
#include <string.h>
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<s2)
//printf("%d\n", 'a', 'A');
char s1[] = "abc";
char s2[] = "abc";
printf("%d\n", s1==s2); //直接比较两个数组,相当于地址的比较,所以总是不相等的,输出0
if( strcmp(s1, s2) == 0 ) {
printf("s1=s2\n"); //s1=s2
}
char s3[] = "bbc";
printf("%d\n", strcmp(s1, s3)); // -1
char s4[] = "Abc";
printf("%d\n", strcmp(s1, s4)); //32 , 小写字母比大写字母大,返回值为它们之间的差值
printf("%d\n", 'a' - 'A'); //32
char s5[] = "abc ";
printf("%d\n", strcmp(s1, s5)); //-32 , 前三个字母相等,比较到第四个的时候,0减32(空格的ASCII码32)= -32
/* 比较过程如下:s1[0] == s2[0] ?
------------------
| a | b | c | \0 |
|-----------------
|| || ||
-----------------------
| a | b | c | 空格| \0 |
|----------------------
*/
//char *strcpy(char *restrict dst, const char *restrict src);
//把src的字符串拷贝到dst
//restrict表明src和dst不重叠(C99)
//返回dst
//为了能链起代码来
//char * strcat(char *restrict s1, const char *restrict s2);
//把s2拷贝到s1的后面,接成一个长的字符串
//返回s1
//s1必须具有足够的空间
//strcpy和strcat都可能出现安全问题
//如果目的地没有足够的空间
//安全版本:
//char * strncpy(char *restrict dst, const char *restrict src, size_t n);
//char * strncat(char *restrict s1, const char *restrict s2, size_t n);
//int strncmp(const char *s1, const char *s2, size_t n);
//字符串中找字符
char * strchr(const char *s, int c);
char * strrchr(const char *s, int c);
//返回NULL表示没有找到
return 0;
}
Link:http://www.cnblogs.com/farwish/p/4271457.html
@黑眼诗人 <www.farwish.com>
来源:https://www.cnblogs.com/farwish/p/4271457.html