指针和字符串

一、一级指针

1.定义:类型*->定义指针变量

        *变量名->解引用(间接引用符)

2.指针变量保存相同数据类型的地址值

例如:int a=10;     int *p=&a;

3.错误指针:野指针或叫悬挂指针。

例 int *p;//p没有指向任何的变量的地址;

  Int *p=NULL;//空指针,不能对其进行解引用

二、.指针与数组的关系:

1.数组退化为指针,通常是在函数声明和实现的时候。例:int Show(int arr[],int len)->int Show(int *arr,int len)  

 2.数组和指针的用法:arr+1 ->加单元格(与类型有关,比如是整型的话加4个单元格,等等)

3.指针和数组的转换*(arr+1)<=>arr[1]   *arr=arr[1]

4.定义函数时如何一次性返回多个值?

第一想法应该是用数组来返回,因为数组可以存储多个值,但是上述1.中提到了数组的退化,进一步就可以想到应该用指针来解决。方法如下:

函数定义为Void(无返回值)在声明函数时,可用指针来定义想要返回的值,在函数实现后,调用时,用指针的解引用来获取传回到主函数的值。例如

void Operate(int a,int b,int *sum,int *mul)//定义指针类型

{

    Int *sum=a+b;

    Int *mul=a*b;

}

Int main()

{

Int sum,mul;

Operate(1,2,&sum,&mul);//指针的解引用,

printf(“%d  %d\n”,sum,mul);

}

总结:形参的结果如果要影响实参,必须定义指针,然后对指针进行解引用

三、const 与指针结合

  1. const int *p=&a;//const在*之前,代表它修饰的是p指向的变量的值,一旦这样定义了就相当于const修饰了变量a;a的值就确定了,不能被改变,所以*p不能改变了,但对于p指向的问题并没有特别的说明,所以指向是可以变的,但是*p的值不能变了。

           int a=1,b=2;

          const int *p=&a;

        *p=10;//error

            p=&b;//right

2.int *const p=&a;//const在p之前,表明const修饰的是p的指向问题,一经定义,p就只能指向a的地址,不能更改,但另一方面,const对于p指向的变量a的值并没有限定,所以可以通过*p来更改a的值。

       int a=1,b=2;

        int *const p=&a;

      p=&b;//error

     *p=20;//right

3.const int a=1;//a的值被const修饰,表明a的值已经确定不能更改,那当我们要用指针获取a的地址的时候,要特别注意定义指针时const应该放的位置。要确保a的值不能被改变,所以const应该去修饰*p。

               const int a=1;

              const int *p=&a;//right

               Int *p=&a;//error

4.普通定义情况下,可以通过*p改变常变量a的值,这与先前对a的定义不相符,所以是错误的,必须要用到const锁定*p,让他不能改变a的值

5.两个const,让p的指向和p指向的变量的值都不变。

Const int *const p

四、字符串

  1. 字符串定义

方1:char arr[] = {'h','e','l','\0','l','o'}; //6

arr -> sizeof(arr)/sizeof(arr[0]);//6

 strlen(arr); //3;

方2:const char* str=“hello

       Str->strlrn(str)->5

方3:char arr[] = {'h','e','l','l','o'};

arr -> sizeof(arr)/sizeof(arr[0]);   //5

      strlen(arr);  //5

方4: char arr[] = "hello";  //h e l l o \0  arr大小6

arr[0] ->'h'

总结:若与sizeof在一个函数中,则可用sizeof(arr)/sizeof arr([0] ,sizeof求得的是数组长度;

可用头文件#include中的函数strlen()求得字符串长度,strlen计算的是字符串的有效长度,且不包括‘\0’,strlen()‘\0’一直向后遍历,直到“\0后停止计数,

定义字符常量:const char *str=hello,既然时字符常量那就不应该让*str去改变它的值,所以在*str的前面加上一个const.

字符串结尾标记:‘\0,在没有人为去加上结束标记时,c++的系统会自动为字符串的结尾加’\0.

2.字符串的相关操作:

1)strcmp(const char*str1,const char*str2);  //比较大小功能

字符串比较的源代码:

int my_strcmp1(const char* str1, const char* str2) {

    assert(str1 != NULL && str2 != NULL);

    int i = 0;

    while (*str1 == *str2) { //abc       abc

        if (*str1 == '\0' && *str2 == '\0') {

            return 0;

        }

        str1++;

        str2++;

    }

    return *str1 > *str2 ? 1 : -1;

}

2)strcat(char* str1, const char* str2)//将两个数组合并起来,源代码如下:

char* my_strcat(char* str1, const char* str2) {

    assert(str1!=NULL && str2!=NULL);

    int len = strlen(str1);

    // 给str1后连接str2数据

    int i = 0;

    for (;i < strlen(str2); i++) {

        str1[len+i] = str2[i];

    }

    str1[len+i] = '\0'; // 字符串结尾标记'\0'

    return str1;

}

3)strlen(const char* str)//求字符串长度,源代码如下:

unsigned int my_strlen() {  //"abc\0abc"

    assert(str != NULL);

    unsigned int count = 0;

    while (*str != '\0') {

        count++;

        str++;

    }

    return count;

}

4)strcpy(char* str1, const char* str2)//拷贝

指针方式

char* my_strcpy(char* str1, const char* str2)//指针方式

{

    assert(str1 != NULL && str2 != NULL);

    while (*str2!='\0') { //abc\0     abc

        *str1 = *str2;

        str1++;

        str2++;

    }

    *str1 = '\0';

return str1;  

数组方式:

char* my_strcpy(char* str1, const char* str2) {

    assert(str1 != NULL && str2 != NULL);

int i = 0;

    for (; i < strlen(str2); i++) {

        str1[i] = str2[i];

    }

    str1[i] = '\0';

    return str1;*/

}

你可能感兴趣的:(c语言,c++,指针,字符串)