2019年7月12日星期五(C语言)

一、字符数组?

1、什么是字符数组?

一个数组中全部成员都是字符来的。

例子: char A[5];

2、字符数组赋值?

1)定义同时初始化?

char A[10] = {'h','e','l','l','o'};  -> 剩余没有赋值的5个元素都为0

char A[10] = {"hello"};              -> 将字符串hello赋值给数组

char A[10] = {"10086"};     -> char A[10]已经决定每一个成员都是字符类型,所以 '1','0','0','8','6'

int A[10] = {1,0,0,8,6};    -> int A[10]已经决定每一个成员都是整型类型,所以 1,0,0,8,6

char A[10] = "hello";    -> {}可以省略!

3、将字符串常量赋值给数组在内存中是如何变化?

int a = 10;

char A[10] = "hello";

其实将常量区中的值赋值给栈区空间。

1)注意:

所有字符串常量在常量区存在都会以''作为结束的标志。

Oct   Dec   Hex   Char

000   0     00    NUL ''

2)例如:

helloworldappletree

二、字符指针?

整型指针 -> int类型

字符指针 -> char类型

例子1

char a = 'h';

char *p = &a;  -> p就是字符指针  -> 指向一个字符类型的数据a

例子2

char *p = "hello";  -> 正确!

究竟p指向字符?还是指向一个字符串?

字符指针p永远只能指向字符,不可能指向整个字符串,在这个例子,p指向"hello"这个字符串的首元素'h'的地址

注意:

1)p是一个指针变量,所以只能存放地址,存放着是hello中'h'的地址。

2)p是一个指针变量,不能存放字符串,不是将常量区的hello拷贝过来。

3)字符指针只能指向字符,不能指向字符串。

4)%s 输出字符串

输出原则:给定一个地址,判断地址上值是不是''

          如果不是,则打印该地址上的值并将该地址往后挪动一个单位。

          如果是,就停止打印。

 

 

请问以下代码是什么含义?

char A[10] = "hello";

char *p = "hello";

printf("A = %s ",A);  //A是字符串首元素的地址,结果:hello   -> 打印的是栈区的hello

printf("p = %s ",p);  //p是字符串首元素的地址,结果:hello   -> 打印的是常量区的hello

结论:

1)只要将一个字符串赋值给一个字符数组,那么就会把常量区的字符串拷贝到该字符数组中。

2)只要将一个字符串赋值给一个字符指针,那么该指针就是存放着这个字符串的首元素的地址。

#include <stdio.h>

int main(int argc,char *argv[])

{

       char A[] = "helloworld";

       char *p = "helloworld";

       char *pa = A; //pa等价于数组名A,使用pa来访问东西,都是属于栈区!

       printf("sizeof(A) = %d ",sizeof(A));//11

       printf("sizeof(p) = %d ",sizeof(p));//4

       printf("A = %s ",A); //helloworld

       printf("*A = %c ",*A); //h  栈区

       printf("*(A+1) = %c ",*(A+1)); //e  栈区

       printf("A+1 = %s ",A+1); //elloworld  栈区

       printf("p = %s ",p); //helloworld  常量区

       printf("pa = %s ",pa); //helloworld  栈区

       printf("A[0] = %c ",A[0]); //h 栈区

       A[0] = 'k';

       printf("A = %s ",A); //kelloworld  栈区

      

       printf("*p = %c ",*p); //h  常量区

       //*p = 'k';  //26行段错误,原因常量区不能修改值。

       //printf("p = %s ",p);

       printf("*pa = %c ",*pa); //k  栈区

       pa[0] = 'm';

       printf("pa = %s ",pa); //melloworld

       return 0;

}

14、有以下程序

main()

{   

       char s[]=“Yes /No”,*ps=s;

        puts(ps+4);

        *(ps+4)=0;

        puts(s);

}

程序运行后的输出结果是( B )

A) n/No      B) /No     C) n/No     D) /No

   Yes          Yes        Yes         /No

   /No                     /No         Yes

16、有以下程序                             

main()                               

{  

       char s[]= “ABCD”,*p;             

        for(p=s+1;p<s+4;p++) 

              printf(“%s ”,p);

}  

程序运行后的输出结果是()

BCD

CD

D

 

17、以下程序运行后的输出结果是( gae )

main()

{  

       char a[]=“Language”,b[]=“Programe”;

        char *p1,*p2; 

       int k;

        p1=a;p2=b;

        for(k=0;k<8;k++)

           if(*(p1+k)==*(p2+k))   等价于 if(p1[k] == p2[k])

               printf(“%c”,*(p1+k));

}

三、指针数组

1、什么是数组指针?什么是指针数组?

数组指针是一个指针来的,这个指针指向整一个数组。

指针数组是一个数组来的,这个数组的每一个成员都是指针。

2、如何定义指针数组?

定义的方法与定义普通数组一致。

1)给一个数组名 p

2)确定元素的个数,使用[]括号括住它  p[5]

3)确定每一个元素的类型  int *pa

4)将第3步的变量名去掉  int*

5)将第4步的结果写在第2步结果的前面   int* p[5]  -> 指针数组

3、如何定义数组指针?

int A[5];

int (*p)[5]; = &A;  --> 数组指针

练习:  提示: strlen()计算字符串实际长度

15、有以下程序        

main()

{  

       char str[][20]={“Hello”,”Beijing”},*p=str[0];

         printf(“%d ”,strlen(p+20));

}  

程序运行后的输出结果是( C )

A)   0     B)  5     C)  7    D)  20

18、有以下程序

main()

{  

       char *p[10]={“abc”, “aabdfg”, “dcdbe”, “abbd”, “cd”};

        printf(“%d ”,strlen(p[4]));

}  

执行后输出结果是( A )

A) 2      B) 3      C) 4      D) 5

19、若有定义:int *p[3];,则以下叙述中正确的是( B )

A)定义了一个基类型为int的指针变量p,该变量具有3个指针。

B)定义了一个指针数组p,该数组含有3个元素,每个元素都是基类型为int的指针。

C)定义了一个名为*p的整型数组,该数组含有3个int类型元素。

D)定义了一个可指向一维数组的指针变量p,所指一维数组应具有3个int类型元素。

 

若有以下程序:

void main()

{

       char *a[3] = {"I","love","China"};

       char **ptr = a;

       printf("%c %s",*(*(a+1)+1),*(ptr+1));  // 'o'   "love"

}

四、const指针?

1、什么是const指针?

已经学习了非常多指针种类,例如:整型指针int*、字符指针char*  -> 指的是指针的类型

const指针并不是指针的类型,只是用于修饰特定的指针类型。

2、使用场景?

一般const作用形式参数。

例子:

int fun(int a); //a=10 ->   可以随时通过a修改a本身的值。

int fun(const int a); //a=10  一旦a被初始化后,不能通过a修改a的值。

int main()

{

       fun(10);

}

结论: const修改了某个变量之后,就不能通过该变量修改该变量里面的值。

3、 例子:

#include <stdio.h>

int main()

{

       /* const作用于整型变量

       const int a;//使用const修饰变量a,一旦变量初始化随机值之后,就不能通过a修改a的值

       a = 100; //编译出错: error: assignment of read-only variable ‘a’

       printf("a = %d ",a);

       //a = 200; //编译出错: error: assignment of read-only variable ‘a’

       //printf("a = %d ",a);

       */

       /* const作用于指针变量本身

       int a = 100;

       int b = 50;

       int * const p = &a; //const修饰p的本身,所以一旦p被初始化之后,就不能通过p修改p的本身

       //p = &b; //编译出错:error: assignment of read-only variable ‘p’

       *p = 200;  //正确的,因为const修饰p的本身,但是没有修饰p指向的内容,所以可以通过p修改p指向的内容

       printf("a = %d ",a);

       */

       /* const修饰指针变量指向的内容

       int a = 100;

       int b = 50;

       const int *p = &a; //const修饰p指向的内容,而不是修饰p

       p = &b;  //可以通过p修改p本身。

       //*p = 200; //编译出错:error: assignment of read-only location ‘*p’

                       //不可以通过p修改p指向的内容。    

       b = 200; //可以,没有通过p修改p指向的内容

       */   

       return 0;

}

4、结论

int * const p;   -> const修饰p的本身,一旦p被赋值了某个一个地址之后,就不能通过p修改p的地址。

                  int * const p = xxxx地址(正确)   p = yyyy地址(错误)

               -> 但是可以通过p修改p指向的内容。

                   *p 随便搞

 

const int *p;   等价  int const *p;

              -> const修饰p指向的内容,p随意指向任何的地址

                const int *p  = xxxx地址(正确)   p = yyyy地址(正确)

                   *p 出现错误

五、字符串函数

1、字符串在程序中如何保存使用?

char A[10] = "hello";  -> 将常量区"hello"拷贝到数组A内存空间。

char *p = "hello";     -> 将常量区"hello"首元素的地址保存在指针变量p中。

2、在linux下,有些关于字符串函数提供用户使用。

1)计算字符串实际长度  -> strlen()

2)比较两个字符串是否匹配  -> strcmp()

3)拷贝字符串到某段内存中  -> strcpy()

4)追加字符串   -> strcat()

六、计算字符串实际长度  -> 不包含''在内    Ubuntu:man 3 strlen

NAME  -> 函数的功能

strlen - calculate the length of a string  -> 校对字符串长度

#include <string.h>  -> 头文件

size_t strlen(const char *s);  -> 函数原型

 s: 需要计算的字符串的首元素的地址

返回值:字符的个数。

例子:

#include <stdio.h>

#include <string.h>

 

int main()

{

       char A[100] = "helloworld";

       char *p = "helloworld";

       printf("sizeof(A) = %d ",sizeof(A));//100

       printf("sizeof(p) = %d ",sizeof(p));//4

       printf("strlen(A) = %d ",strlen(A));//10

       printf("strlen(p) = %d ",strlen(p));//10

       return 0;

}

  结论: sizeof()计算空间大小,strlen()计算字符串的长度。

七、比较两个字符串是否匹配  -> strcmp()

1、与整型变量是否相等比较

   int a = 200;

   int b = 100;

   if(a == b)   -> 整型数据使用"=="来进行判断

2、比较两个字符串能不能用"=="?

   char A[100] = "helloworld";

   char *p = "helloworld";

   if(A == p)  -> 不可以,只能判断两个地址是否相等,这样对比是没有任何意义,只有对比内容才有意义。

3、 如何比较两个字符串?  -> 只能使用strcmp()  ->  man 3 strcmp

NAME

strcmp, strncmp - compare two strings  比较两个字符串

#include <string.h>

int strcmp(const char *s1, const char *s2);

int strncmp(const char *s1, const char *s2, size_t n);

  s1:需要进行比较的字符串1的地址

  s2:需要进行比较的字符串2的地址

  n: 只匹配前n个字节

 

返回值:

       s1与s2匹配  -> 0

       s1与s2不匹配  -> 非0

4、例子:

#include <stdio.h>

#include <string.h>

int main()

{

       int ret;

       char A[100] = "helloworld";

    char *p = "hello";

      

       ret = strncmp(A,p);

       if(ret == 0)

       {

              printf("match! ");

       }

       else{

              printf("no match! ");

       }

      

       return 0;

}

练习:有一张银行卡,密码是gec123456,请求用户输入密码,如果密码正确,则输出密码的长度,如果密码错误,则重新输入!如果输入的次数超过5次,则程序直接退出。

#include <stdio.h>

#include <string.h>

int main(int argc,char *argv[]) 

{

       char passwd[20] = "gec123456"; //银行卡密码

       char input_passwd[20] = {0}; //清空数组

       char *p = input_passwd;

       int count = 0;

       while(count < 5)

       {

              scanf("%s",p);

      

              if(strcmp(passwd,p) == 0)

              {

                     printf("passwd length = %d ",strlen(passwd));

                     break;

              }

              else{

                     count++;

                     continue;

              }

       }

      

       return 0;

}

八、拷贝字符串到某段内存中  -> strcpy()

char A[10] = "hello";

char A[10] = {"hello"};

char A[10] = {'h','e','l','l','o'};

char A[10];   -> 如果定义没有初始化,则以后都不能整体初始化。

A[0] = 'h';

...

strcpy()  -> 如果定义没有初始化,则以后还能使用strcpy()整体初始化。  -> man 3 strcpy

 

char A[10];

A = "hello"        //错误

strcpy(A,"hello"); //正确

NAME

strcpy, strncpy - copy a string

SYNOPSIS

#include <string.h>

char *strcpy(char *dest, const char *src);

char *strncpy(char *dest, const char *src, size_t n);

  dest:需要把字符串拷贝到的空间的起始地址,这个空间必须足够大。

  src:需要拷贝的字符串的地址。

  n: 只拷贝srcn个字节

返回值:

成功: 返回指向dest内存空间的地址

失败: NULL

#include <stdio.h>

#include <string.h>

int main()

{

       char A[11] = "helloworld";

       char *p = "abc";

       int i;

       for(i=0;i<11;i++)

       {

              printf("A[%d] = %c ",i,A[i]);

       }

      

       strcpy(A,p);

       for(i=0;i<11;i++)

       {

              printf("A[%d] = %c ",i,A[i]);

       }

       printf("A = %s ",A);

       return 0;

}

原文地址:https://www.cnblogs.com/zjlbk/p/11178035.html