-----------------------------------------------------------------------------
// 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. 指針變量的值是具有實際值的變量的地址
*/
/*
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拷貝到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>