目录

  • 1 第一章 C语言简介
    • 1.1 C语言前世今生
    • 1.2 主流开发环境介绍
    • 1.3 第一个小程序解析
    • 1.4 常见编译错误
    • 1.5 章节知识点小结
  • 2 算法基础
    • 2.1 算法-程序的灵魂
    • 2.2 算法的描述-流程图
  • 3 数据类型与运算符
    • 3.1 数据描述
    • 3.2 运算符和表达式1
    • 3.3 运算符和表达式2
    • 3.4 章节知识点小结
  • 4 顺序结构程序设计
    • 4.1 输入和输出
    • 4.2 顺序结构程序设计
    • 4.3 章节知识点小结
  • 5 选择结构程序设计
    • 5.1 关系运算符和关系表达式
    • 5.2 逻辑运算符和逻辑表达式
    • 5.3 if语句
    • 5.4 条件运算符
    • 5.5 switch语句
    • 5.6 章节知识点小结
  • 6 循环结构程序设计
    • 6.1 while循环结构
    • 6.2 do_while循环结构
    • 6.3 for循环结构
    • 6.4 循环的嵌套
    • 6.5 break语句和continue语句
    • 6.6 章节知识点小结
  • 7 数组
    • 7.1 一维数组
    • 7.2 二维数组
    • 7.3 字符数组
    • 7.4 章节知识点小结
  • 8 函数
    • 8.1 子程序设计
    • 8.2 函数定义
    • 8.3 函数的调用
    • 8.4 局部变量和全局变量
    • 8.5 参数传递
    • 8.6 函数递归调用
    • 8.7 章节知识点小结
  • 9 指针
    • 9.1 指针的基本概念
    • 9.2 指针变量的定义及引用
    • 9.3 通过指针引用数组元素
    • 9.4 指向多维数组的指针和指针变量
    • 9.5 用指向数组的指针作函数参数
    • 9.6 指针与字符串
    • 9.7 函数指针和指针函数
    • 9.8 章节知识点小结
  • 10 用户自己建立数据类型
    • 10.1 定义和使用结构体变量
    • 10.2 使用结构体数组
    • 10.3 结构体指针
    • 10.4 章节知识点小结
  • 11 编译预处理
    • 11.1 宏定义预处理
    • 11.2 文件包含预处理
    • 11.3 条件编译预处理
    • 11.4 章节知识点小结
  • 12 文件
    • 12.1 文件的基本知识
    • 12.2 文件的基本操作
    • 12.3 章节知识点小结
指针与字符串


 C语言对字符串常量按字符数组来处理,在内存中开辟一段连续的空间存放字符串常量。对字符指针变量p的初始化,是把字符串第一个元素的地址赋给p

1、字符串的表示形式

  在C程序中,可以用两种方法访问一个字符串:(1)用字符数组存放一个字符串,然后输出该字符串;(2)用字符指针指向一个字符串。

//定义一个字符数组,对它初始化,然后输出该字符串

#include<stdio.h>

int main(){

    charstring[]="I love China!";

    printf("%s\n",string);

    return0;

}

和前面介绍的数组属性一样,string 是数组名,它代表字符数组的首元素的地址。string[4]代表数组中序号为4的元素(它的值是字母v),实际上string[4]就是善(string+4)string+4是一个地址,它指向字符“v”

//可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。

#include<stdio.h>

int main(){

    char *string="I love China!";

    printf("%s\n",string);

    return0;

}

在这里没有定义字符数组,在程序中定义了一个字符指针变量string,用字符串常量“I loveChina!"对它初始化。C语言对字符串常量是按字符数组处理string的,在内存中开辟了一个字符数组用来存故该字符串常量。对字符指针C变量string初始化,实际上是把字符串第1个元素的地址(即存放字符串的字符数组的首元素地址)string。有人误认为皮,string是一个字符串变量,以为在定义时把“I loveChina!"这几个字符赋给该字符串变量,这是不对的。定义string的部分:

char *string="I love China!"

等价于:

char *string;                                                                                                                                                                                                                                     string="I love China!";

可以看到string被定义为一个指针变量,指向字符型数据,请注意它只能指向一个字符变量或其他字符类型数据,不能同时指向多个字符数据,更不是把“I loveChina!"这些字符存放到string(指针变量只能存放地址),也不是把字符串赋给* string。只是把“I loveChina!"的第1个字符的地址赋给指针变量string

  输出时用printf("%s\n",string);%s是输出字符串时所用的格式符,在输出项中给出字符指针变量名string,则系统先输出它所指向的一个字符数据,然后自动使string1,使之指向下一个字符,然后再输出一个字符.....如此直到遇到字符串结束标志'\0'为止。注意,在内存中,字符串的最后被自动加了一个‘\0',因此在输出时能确定字符串的终止位置。说明:通过字符数组名或字符指针变量可以输出一个字符串。而对一个数值型数组,是不能企图用数组名输出它的全部元素的。

//将字符串a复制为字符串b

#include<stdio.h>

int main(){

    int i;

    char a[]="I am a boy!",b[20];

    for(i=0;*(a+i)!='\0';i++)

        *(b+i)=*(a+i);

    *(b+i)='\0';

    printf("string a is%s\n",a);

    printf("string b is");

    for(i=0;*(b+i)!='\0';i++)

        printf("%c",b[i]);

    printf("\n");

    return0;

}

运行结果:

https://img2018.cnblogs.com/blog/1239274/201809/1239274-20180922101715891-127346810.jpg

程序中ab都定义为字符数组,可以通过地址访问其数组元素。在for语句中,先检查a[i]是否为'\0'(a[i]是以*(a+i)形式表示的)。如果不等于'\0’,表示字符串尚未处理完,就将a[i]的值赋给b[i],即复制一个字符。在for循环中将a串全部复制给了b串。最后还应将'\ 0复制过去,即:*(b+i)='\0'

//也可以用指针变量,用它的值的来改变来指向字符串中不同的字符

#include<stdio.h>

int main(){

    char a[]="I am a boy!",b[20],*p1,*p2;

    int i;

    p1=a;

    p2=b;

    for(;*p1!='\0';p1++,p2++)

        *p2=*p1;

    *p2='\0';

    printf("string a is%s\n",a);

    printf("string b is");

    for(p2=b;*p2!='\0';p2++)

        printf("%c",*p2);

    printf("\n");

    return0;

}

p1p2是指向字符型数据的指针变量。先使p1p2的值分别为字符串ab1个字符的地址。* p1最初的值为‘I’,赋值语句“*p2=*p1的作用是将字符'I'(a串中第1个字符)赋给p2所指向的元素,即b[0]。然后p1p2分别加1,指向其下面的一个元素,直到*pl的值为'\0'止。注意p1p2的值是不断在改变的,程序必须保证p1p2同步移动。

2、字符指针作函数参数

  将一个字符串从一个 函数传递到另一个 函数,可以用地址传递的办法,即用字符数组名作参数,也可以用指向字符的指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。

//用函数调用实现字符串的复制,用字符数组作参数

#include<stdio.h>

void copy(char a[],char b[]){

    int i=0;

    while(a[i]!='\0'){

        b[i]=a[i];

        i++;

    }

    b[i]='\0';

}

int main(){

    char a[]="I am a teacher!";

    char b[]="You are a student!";

    printf("stringa=%s\nstring b=%s",a,b);

    printf("\ncopystring a to b\n");

    copy(a,b);

    printf("stringa=%s\nstring b=%s",a,b);

    return0;

}

运行结果:

https://img2018.cnblogs.com/blog/1239274/201809/1239274-20180922120708286-2004462398.jpg

注意:b数组最后3个元素仍保留原状。在输出b时由于按%s(字符串)输出,遇'\0'即告结束,因此第一个'\0'后的字符不输出。如果不采取%s格式输出而用%c逐个字符输出是可以输出后面这些字符的。在main函数中也可以用字符型指针变量作实参,先使指针变量ab分别指向两个字符串。函数可改写如下:

#include<stdio.h>

void copy(char a[],char b[]){

    int i=0;

    while(a[i]!='\0'){

        b[i]=a[i];

        i++;

    }

    b[i]='\0';

}

int main(){

    char m[]="I am a teacher!";

    char n[]="You are a student!";

    char *a=m,*b=n;

    printf("stringa=%s\nstring b=%s",a,b);

    printf("\ncopystring a to b\n");

    copy(a,b);

    printf("stringa=%s\nstring b=%s",a,b);

    return0;

}

以下程序是以形参用字符指针变量实现的:

#include<stdio.h>

void copy(char *a,char *b){

    for(;*a!='\0';a++,b++){

        *b=*a;

    }

    *b='\0';

}

int main(){

    char a[]="I am a teacher!";

    char b[]="You are a student!";

    printf("stringa=%s\nstring b=%s",a,b);

    printf("\ncopystring a to b\n");

    copy(a,b);

    printf("stringa=%s\nstring b=%s",a,b);

    return0;

}

3、小结

字符数组:由若干个元素组成,每个元素是一个字符;

字符指针变量:存放字符串第1个字符的地址。

赋值方式:字符数组只能对单个元素赋值,而允许对字符指针变量赋值

对字符指针变量赋初值:

    char *a= love China;等价于

    char  *a;

   a=″I love China

而对数组的初始化:

   char  str14]=love  China″;

   不等价于

   char str14];

   str[]=″I love China