mg4377娱乐娱城官网_mg4377娱乐手机版_www.mg4377.com

mg4377娱乐手机版:c语言指针字符串,字符串和指

时间:2019-07-06 05:02来源:mg4377娱乐手机版
证实:这些C语言专题,是上学iOS开垦的序曲。也为了让有面向对象语言开垦经历的程序猿,可以神速上手C语言。如若您还未曾编制程序经验,或然对C语言、iOS开荒不感兴趣,请忽略

证实:这些C语言专题,是上学iOS开垦的序曲。也为了让有面向对象语言开垦经历的程序猿,可以神速上手C语言。如若您还未曾编制程序经验,或然对C语言、iOS开荒不感兴趣,请忽略

用数组完结的字符串和用指针完毕的字符串

char str[] = "ABC"; //用数组实现的字符串char *pstr = "123"; //用指针实现的字符串

依据上例:

[C语言]指南针与字符串,c语言指针字符串

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

//  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)=%ldn", sizeof(a)); //4

    printf("sizeof(int)=%ldn", sizeof(int)); //4

    //4. double变量在内存中占据的空间是int变量的两倍
    //5. 地址的大小是否与int相同取决于编译器,取决于是32位还是64位架构,并不总是相同

    printf("sizeof(int)=%ldn", sizeof(double)); //8
    printf("%lun", sizeof(&a));  //8(64位架构),32为架构下int和地址都是4个字节

    printf("0x%xn", &a);      //0x5fbff82c, %x代表输出十六进制
    printf("%pn", &a);        //0x7fff5fbff82c(64位架构下),32位架构下为0x5fbff82c
    printf("%pn", b);         //0x5fbff82c

    //5. 相邻地址的差距永远是4

    int c[10];

    printf("%pn", &c);       //0x7fff5fbff810
    printf("%pn", &c[0]);    //0x7fff5fbff810
    printf("%pn", &c[1]);    //0x7fff5fbff814

    printf("%pn", c);        //0x7fff5fbff810
    printf("%pn", c[0]);     //0x0
    printf("%pn", 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=%pn", &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=%pn", p);
    return 0;
}

int k(int p) {
    printf("p=%dn", p);
    return 0;
}

int g(int *p) {
    printf("p=%dn", *p);
    *p = 10;    //更改了i的值
    return 0;
}

int m(int *p) {
    printf("p=%dn", *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)=%lun", sizeof(a));  //main sizeof(a)=24

    printf("main a=%pn", a);                   //main a=0x7fff5fbff820

    minmax(a, sizeof(a)/sizeof(a[0]), &min, &max);

    printf("a[0]=%dn", a[0]);                  //a[0]=1

    printf("min=%d, max=%dn", min, max);

    int *p = &min;
    printf("*p=%dn", *p);      //*p=1
    printf("p[0]=%dn", p[0]);  //p[0]=1, 对于指针变量,可以采用数组的写法
    printf("*a=%dn", *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)=%lun", sizeof(a));//minmax sizeof(a)=8 , 32位架构下为4

    printf("minmax a=%pn", 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 = %cn", c);  //1

    printf("c = %dn", c);  //49 ,以整数形式

    printf("c2 = %dn", c2);//97,代表整数

    printf("d = %cn", d);  //空

    if(c == d) {
        printf("c = dn");
    } else {
        printf("c != dn");
    }    

    printf("==========n");

    /*
     scanf只能以整数形式输入:
     1. 输入49时,%c形式输出1,%d形式输出49
     2. '1'的ASCII编码是49,所以当i==49时,它代表'1'
     */
    scanf("%d", &i);    
    printf("i = %cn", i);

    printf("i = %dn", i);

    if(49 == '1') {
        printf("right!n");
    }    

    printf("==========n");    

    /*
     字符计算:
     1. 一个字符加一个数字得到ASCII码表中那个数之后的字符
     2. 两个字符的减,得到它们在表中的距离
     */
    char e = 'A';
    e  ;
    printf("%cn", e);  //B

    int f = 'Z' - 'A';
    printf("%dn", f);  //25

    //字母在ASCII表中是顺序排列的
    //大写字母和小写字母是分开排列的,'a'-'A'可以得到两段的距离;
    //所以把一个大写字母变成小写字母:a 'a'-'A',把一个小写字母变成大写字母:a 'A'-'a'  

    /*

     逃逸字符:

   用来表述无法打字与印刷出来的调控字符或特殊字符,由三个反斜杠“mg4377娱乐手机版:c语言指针字符串,字符串和指针。”伊始,前面跟上另贰个字符,那多少个字符合起来,组成了贰个字符

     b 回降一格(但不删除)    //backspace

     t 制表位,每行固定的岗位  //tab

     n 换行(由于打字机上换行和回车是四个字符,所以c语言也是将它们分其他)  //newline

     r 回车           //return

     " 双引号

     ' 单引号

     \ 反斜杠自己

     */

     printf("123bn456n");

     printf("123t456n");

     printf("12t456");

   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=%lun", strlen(line));       //strlen=5
    printf("sizeof=%lun", sizeof(line));       //sizeof=6

    //int strcmp(const char *s1, const char *s2);
    //比较两个字符串,返回:0(s1==s2),1(s1>s2),-1(s1<s2)
    //printf("%dn", 'a', 'A');

    char s1[] = "abc";
    char s2[] = "abc";

    printf("%dn", s1==s2); //直接比较两个数组,相当于地址的比较,所以总是不相等的,输出0

    if( strcmp(s1, s2) == 0 ) {
        printf("s1=s2n");  //s1=s2
    }

    char s3[] = "bbc";

    printf("%dn", strcmp(s1, s3)); // -1

    char s4[] = "Abc";

    printf("%dn", strcmp(s1, s4)); //32 , 小写字母比大写字母大,返回值为它们之间的差值
    printf("%dn", 'a' - 'A');  //32

    char s5[] = "abc ";
    printf("%dn", 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:

@黑眼作家 <www.farwish.com>

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

字符串回看

一个字符串由一个或多少个字符组成,由此大家得以用字符数组来存放在字符串,可是在数组的尾巴部分要抬高叁个空字符'\0'。

char s[] = "mj";

地点的代码定义了叁个字符数组s来储存字符串"mj",系统会活动在尾巴部分加上四个空字符'\0'。

内部存款和储蓄器遍布大约如右图所示:mg4377娱乐手机版 1

 

从上一篇小说《十二、指向一维数组成分的指针》中能够见到指针和数组的涉及特别留心,因而大家也足以行使指针来操作字符串。

用数组达成的字符串str

strchar[4]型的数组(成分类型为char型,元素个数为4的数组)。个元素从头起头依次用'A','B','C','\0'举行开始化。char数组攻下的内部存款和储蓄器空间和数组的个数一致。这里是4字节,可以透过表明式sizeof求得

// main.c // Created by weichen on 15/2/1. // Cop...

//  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)=%ldn", sizeof(a)); //4            printf("sizeof(int)=%ldn", sizeof(int)); //4            //4. double变量在内存中占据的空间是int变量的两倍      //5. 地址的大小是否与int相同取决于编译器,取决于是32位还是64位架构,并不总是相同        printf("sizeof(int)=%ldn", sizeof(double)); //8      printf("%lun", sizeof(&a));  //8(64位架构),32为架构下int和地址都是4个字节            printf("0x%xn", &a);      //0x5fbff82c, %x代表输出十六进制      printf("%pn", &a);        //0x7fff5fbff82c(64位架构下),32位架构下为0x5fbff82c      printf("%pn", b);         //0x5fbff82c            //5. 相邻地址的差距永远是4            int c[10];            printf("%pn", &c);       //0x7fff5fbff810      printf("%pn", &c[0]);    //0x7fff5fbff810      printf("%pn", &c[1]);    //0x7fff5fbff814            printf("%pn", c);        //0x7fff5fbff810      printf("%pn", c[0]);     //0x0      printf("%pn", 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      %[],扫描字符集合   %%,读%符号   */

一、用指针遍历字符串的兼具字符

 1 // 定义一个指针p   2 char *p;   3    4 // 定义一个数组s存放字符串   5 char s[] = "mj";   6    7 // 指针p指向字符串的首字符'm'   8 p = s; // 或者 p = &s[0];   9   10 for (; *p != '\0'; p  ) {  11     printf("%c n", *p);  12 }

实施完第8行后,内部存款和储蓄器布满如右图:mg4377娱乐手机版 2

有了前头指针与数组的功底相信我们能收看第9行未来的代码了:每回遍历此前先推断p当前本着的字符是还是不是为空字符\0,若是或不是空字符,就打字与印刷当前字符,然后实施p 让指针p指向下三个字符成分。

最后的输出结果:mg4377娱乐手机版 3

 

用指针实现的数组ptr

ptr是指向char型变量的指针变量,它的早先值为字符串字面量"123"。对字符串字面量进行判别,能够猎取针对性该字符串字面量第八个字符的指针。所以ptr被初叶化为指向保存在内容中字符串字面量"123"的首先个‘1’的指针。

 

二、用指针直接指向字符串

从后边能够看来,指针确实能够指向字符串并操作字符串。但是后边的做法是:先定义一个字符串数组寄存字符串,然后将数组首地址传给指针p,让p指向字符串的首字符。

诚如景观下,大家把指针p指向字符串字面量"string"的第贰个字符's',称为"指针p指向“string”"。在该程序中,指针p指向"123"。

由于指针指向的不是字符串字面量,而是字符串字面量的第三个字符,因而该表述情势不太准确。然则那是时常应用的抒发情势。

别的指针ptr不得进行如下宣示⚠️。

char *ptr = {'1', '2', '3', '\0'};

指针ptr侵夺的内部存款和储蓄器空间为sizeof,即sizeof字节,其长度因编写翻译器而已。其它,字符串字面量"123"占用sizeof字节,和字符个数4(包括null在内)是一致的。

指南针变量和字符串字面量是各自攻下空间的。指针p是指向字符串第2个字符的指针。别的,数组str也是指向首个字符的指针(因为数组名会被解说为指向发轫成分的指针)。

//  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=%pn", &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=%pn", p);      return 0;  }    int k(int p) {      printf("p=%dn", p);      return 0;  }    int g(int *p) {      printf("p=%dn", *p);      *p = 10;    //更改了i的值      return 0;  }    int m(int *p) {      printf("p=%dn", *p);      return 0;  }

1.大家也得以一直用指针指向一个字符串,省略定义字符数组那一个手续

 1 #include <string.h>   2    3 int main()   4 {   5     // 定义一个字符串,用指针s指向这个字符串   6     char *s = "mj";   7        8     // 使用strlen函数测量字符串长度   9     int len = strlen(s);  10       11     printf("字符串长度:%D", len);  12     return 0;  13 }

只顾第6行,我们一贯用指针s指向了字符串"mj",并未先创建二个字符数组。看第9行,将指针s传入到strlen函数中,表达在此之前所学习的字符串管理函数依旧得以健康使用。输出结果:mg4377娱乐手机版 4

 

用数组达成的字符串和用指针达成的字符串不一样点

char s[] = "ABC";s = "DEF" //❌编译出错char *p = "123";p = "456"; //✅编译正确

就算右侧包车型大巴数组名会被解说为数组开首成分的地址,但依旧不可能改写其值。

要是能够赋值,就能够改动数组的地址(即数组在内部存款和储蓄器空间上运动了)。

⚠️可认为指向字符串字面量的指针赋上指向别的字符串字面量的指针。赋值后,指针指向新的字符串字面量。

 

2.大家再来看看strlen函数在string.h中的评释

size_t     strlen(const char *);

strlen函数中的形参是指向字符变量的指针类型,在《十、字符和字符串常用管理函数》中大家能够将二个字符数组名传进去,这点又证实了指针与数组的紧凑关系,料定有JQ。其实,调用strlen函数时,你传二个地点给它就行了,它会从那几个地点伊始猜度字符的个数,直到蒙受空字符'\0'地点,由此传出指针变量也许数组名都能够。

其余字符串管理函数也是一模一样的:

1 char    *strcpy(char *, const char *); // 字符串拷贝函数  2 char    *strcat(char *, const char *); // 字符串拼接函数  3 int     strcmp(const char *, const char *); // 字符串比较函数

它们的参数都以指向字符变量的指针类型,由此得以流传指针变量或许数组名。

故此printf函数还是能够寻常使用:

char *s = "mj";  printf("%s", s);

输出结果:mg4377娱乐手机版 5

 

字符串数组

char a[][5] = {"LISP", "C", "Ada"};char *p[] = {"PAUL", "X", "MAC"};
  • 用数组达成的字符串的数组......二维数组

    数组a是3行5列的二维数组,占用的内存空间是15字节。因为不用全部字符串的长短都以一模一样的,所以数组中会爆发未利用的有的。:存款和储蓄第一个字符"C"的a[1],就有3个字符的上空a[1][2] ~ a[1][4]从未有过被选取。⚠️:非常短和这个短的字符串同有时候设有的地方下,从空间的利用功能上的话,存在未选取的半空中这一主题材料不容忽视。

  • 用指针实现的字符串的数组......指针数组

指针p是因素类型为char *型,成分个数为3的数组。

数组各要素p[0],p[1], p[2]的早先值分别是指向各字符串字面量的首字符"P","X","M"的指针。因而,除了数组P并吞的多少个sizeof长度的上空之外,还据有3个字符串字面量的半空中(sizeof sizeof sizeof sizeof)字节。

字符串字面量"PAUL"中的字符,能够从头开头按顺序通过p[0][0], p[0][1], ...来拜望。通过连日使用下标运算符[],能够像管理二维数组那样来管理指针数组。

⚠️因为不也许确认保障初步值的字符串字面量是在连年的内部存款和储蓄器单元中保存的,所以在上头的指针数组中,个字符串字面量并非相邻的。

//  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)=%lun", sizeof(a));  //main sizeof(a)=24            printf("main a=%pn", a);                   //main a=0x7fff5fbff820            minmax(a, sizeof(a)/sizeof(a[0]), &min, &max);            printf("a[0]=%dn", a[0]);                  //a[0]=1        printf("min=%d, max=%dn", min, max);            int *p = &min;      printf("*p=%dn", *p);      //*p=1      printf("p[0]=%dn", p[0]);  //p[0]=1, 对于指针变量,可以采用数组的写法      printf("*a=%dn", *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)=%lun", sizeof(a));//minmax sizeof(a)=8 , 32位架构下为4            printf("minmax a=%pn", 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 =  */

3.指针指向字符串的别样办法

char *s;  s = "mj";

上面包车型地铁针对格局也是不错的:先定义指针变量,再指向字符串。假如是字符数组就不容许那样做,下面包车型客车做法是一无可取的:

1 char s[10];  2 s = "mj";

编写翻译器料定报第2行的错,因为s是个常量,代表数组的首地址,不能够张开赋值运算。

还须求专注的是,上边包车型地铁做法也是不当的:

1 char *s = "mj";  2   3 *s = "like";

第3行代码犯了2个谬误:

  • 第3行代码也正是把字符串"like"存进s指向的那一块内部存款和储蓄器空间,由第1行代码可以看看,s指向的是"mj"的首字符'm',也正是说s指向的一块char类型的积存空间,唯有1个字节,要"like"存进1个字节的上空内,鲜明内存溢出
  • 由第1行代码能够看出,指针s指向的是字符串常量"mj"!因而是不能够再经过指针来修改字符串内容的!就到底*s

    'A'那样"看起来就好像准确"的写法也是大错特错的,因为s指向的三个常量字符串,差异意修改它在那之中的字符。

 

 

三、指针管理字符串的注意

当今想将字符串"lmj"的首字符'l'改为'L',消除方案是种种的

//  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 = %cn", c);  //1            printf("c = %dn", c);  //49 ,以整数形式            printf("c2 = %dn", c2);//97,代表整数            printf("d = %cn", d);  //空            if(c == d) {          printf("c = dn");      } else {          printf("c != dn");      }                printf("==========n");            /*       scanf只能以整数形式输入:       1. 输入49时,%c形式输出1,%d形式输出49       2. '1'的ASCII编码是49,所以当i==49时,它代表'1'       */      scanf("%d", &i);          printf("i = %cn", i);            printf("i = %dn", i);            if(49 == '1') {          printf("right!n");      }                printf("==========n");                /*       字符计算:       1. 一个字符加一个数字得到ASCII码表中那个数之后的字符       2. 两个字符的减,得到它们在表中的距离       */      char e = 'A';      e  ;      printf("%cn", e);  //B            int f = 'Z' - 'A';      printf("%dn", f);  //25            //字母在ASCII表中是顺序排列的      //大写字母和小写字母是分开排列的,'a'-'A'可以得到两段的距离;      //所以把一个大写字母变成小写字母:a 'a'-'A',把一个小写字母变成大写字母:a 'A'-'a'  

1.首先种方案

1 // 定义一个字符串变量"lmj"  2 char a[] = "lmj";  3   4 // 将字符串的首字符改为'L'  5 *a = 'L';  6   7 printf("%s", a);

次第常常化运行,输出结果:mg4377娱乐手机版 6

 

    /*

2.应当有人能立即想到第三种方案

1 char *p2 = "lmj";  2 *p2 = 'L';  3   4 printf("%s", p2);

看起来如同是立竿见影的,但那是错误代码,错在第2行。首先看第1行,指针变量p2指向的是一块字符串常量,正因为是常量,所以它里面包车型客车字符是不容许修改的。

有人或然搞蒙了,这里的第1行代码char *p2 = "lmj";跟第一种方案中的第2行代码char a[] = "lmj";不是平等的么?那是不等同的。

  • char a[] = "lmj";定义的是三个字符串变量!
  • char *p2 = "lmj";定义的是四个字符串常量!

     逃逸字符:

   用来表述不可能打印出来的调节字符或特殊字符,由三个反斜杠“”开始,前面跟上另叁个字符,那七个字符合起来,组成了三个字符

     b 回落一格(但不删除)    //backspace

编辑:mg4377娱乐手机版 本文来源:mg4377娱乐手机版:c语言指针字符串,字符串和指

关键词: 语言 字符串 指针