[C语言]指针与字符串

作者: 黑眼诗人
发布时间:2015-07-07 16:46:02

 -----------------------------------------------------------------------------

//  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);      //把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>

标签: C语言
来源:http://www.cnblogs.com/farwish/p/4271457.html

推荐: