Androider学C/C++—(4)数组,指针,引用,struct数据结构

数组

C++数组

  • 定义数组跟java差不多,这里没涉及到对象数组,等学了C++面向对象时候再补上,先TODO
  • 注掉的部分为c++模板部分,还是先TODO
  • 主要内容就是得到数组长度,sizeof(b)/sizeof(a[0])
  • 数组和指针的内容,在下一节数组指针里有说到

    #include <iostream>
    using namespace std;
    //template <class T>
    //
    //
    //int getArrayLen(T& array) {//使用模板定义一 个函数getArrayLen,该函数将返回数组array的长度
    //  return (sizeof(array) / sizeof(array[0]));
    //}

    int main(){

        //cout << "size == " << getArrayLen(a) << endl;
        char a[] = { '1','2','3' };
        int sizea;
        cout << "****************************"<< endl << endl;
        cout << "char a[] = { '1','2','3' }" << endl << endl;
        cout << "sizeof(a) 数组的总字节数长度 == " << sizeof(a) << endl;
        cout << "sizeof(a[0]) 数组中一个元素的步长 == " << sizeof(a[0]) << endl;
        sizea = sizeof(a) / sizeof(a[0]);
        cout << "sizeof(a)/sizeof(a[0]) 数组a长度计算 总长度除以步长  == " << sizea << endl << endl;
        cout << "****************************" << endl << endl;


        int b[5] = { 6,3,2,5,1 };
        int sizeb;
        cout << "int b[5] = { 6,3,2,5,1 }" << endl << endl;
        cout << "sizeof(b) 数组的总字节数长度 == " << sizeof(b) << endl;
        cout << "sizeof(a[0]) 数组中一个元素的步长 == " << sizeof(b[0]) << endl;
        sizeb = sizeof(b) / sizeof(b[0]);
        cout << "sizeof(b)/sizeof(a[0]) 数组b长度计算 总长度除以步长 == " << sizeb << endl << endl;
        cout << "****************************" << endl << endl;


        cout << "**************遍历数组b**************" << endl;

        for (int i = 0; i < sizeb; i++){
            int temp = b[i];
            //cout << "b[" << i << "]" << " == " << b[i] << endl << endl;
            cout << "b[%d]" << i << " == " << b[i] << endl;
        }

        getchar();
        return 0;
    }

输出:


    ****************************

    char a[] = { '1','2','3' }

    sizeof(a) 数组的总字节数长度 == 3
    sizeof(a[0]) 数组中一个元素的步长 == 1
    sizeof(a)/sizeof(a[0]) 数组a长度计算 总长度除以步长  == 3

    ****************************

    int b[5] = { 6,3,2,5,1 }

    sizeof(b) 数组的总字节数长度 == 20
    sizeof(a[0]) 数组中一个元素的步长 == 4
    sizeof(b)/sizeof(a[0]) 数组b长度计算 总长度除以步长 == 5

    ****************************

    **************遍历数组b**************
    b[%d]0 == 6
    b[%d]1 == 3
    b[%d]2 == 2
    b[%d]3 == 5
    b[%d]4 == 1

C数组

  • 指针是一个变量,其值为另一个变量的地址

    #include <stdio.h>
    #include <stdlib.h>
    #define GET_ARRAY_LEN(array,len){len = (sizeof(array) / sizeof(array[0]));}

    //定义一个带参数的 宏,将数组长度存储在变量len中
    int main(){

        char a[] = { '1','2','3','4' };

        int len;

        GET_ARRAY_LEN(a, len)

        //调用预定义的宏,取得数组a的长度,并将其存储在变量len中

        printf("size == %d/n", len);

        system("pause");

        return 0;
    }

C++指针

基本指针的使用

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)或者说是取地址运算符访问的地址,它表示了在内存中的一个地址。


    #include <iostream>

    using namespace std;

    //指针基本使用
    int main()
    {
        int  var1;
        char var2[10];


        int *p;
        p = &var1;
        cout << "var1 变量的地址: ";
        cout << p << endl;

        char *x;
        x = var2;
        cout << "var2 变量的地址: ";
        cout << &x << endl;

        getchar();

        return 0;
    }

输出:

    var1 变量的地址: 0044FEB4
    var2 变量的地址: 0044FEA0

C++ Null 指针

  • 很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。
  • 以下代码不仅演示了如何使用NULL指针,并且还演示了如何判空。

    #include <iostream>

    using namespace std;

    int main()
    {
        int  *ptr = NULL;

        cout << "ptr 的值是 " << ptr << endl;


        //判空

        if (ptr == NULL) {    /* 如果 ptr 非空,则完成 */
            cout << "ptr为空" << endl;
        }
        else
        {

        }

        if (!ptr)    /* 如果 ptr 为空,则完成 */
            cout << "ptr不为空" << endl;

        getchar();

        return 0;
    }

输出:

    ptr 的值是 00000000
    ptr为空
    ptr不为空

C++ 指针的算术运算

  • 我们可以对指针进行四种算术运算:++、–、+、-
  • 加减都好理解,它这个2个指针比较大小就有点抽象了,我个人觉得这个比较的应用场景有限,比如在一个数组中可以通过指针比较大小来判定2个元素的位置或索引谁前谁后。
  • 本例还验证了另一个结论,对数组指针进行了计算之后,它取值也会受到影响,详细见代码。

    #include <iostream>

    using namespace std;
    const int MAX = 3;//常量也能这么定义

    int main()
    {

        //-----------通过指针遍历数组-----------
        cout << "通过指针遍历数组" << endl;
        int  var[MAX] = { 10, 100, 200 };
        int  *ptr;

        // 指针中的数组地址
        ptr = var;
        for (int i = 0; i < MAX; i++)
        {
            cout << "Address of var[" << i << "] = ";//打印对应元素的地址
            cout << ptr << endl;

            cout << "Value of var[" << i << "] = ";//打印对应元素的值
            cout << *ptr << endl;

            // 将指针移动到下一个位置
            ptr++;
        }


        //-----------其他一些奇淫技巧-----------
        cout << "其他一些奇淫技巧" << endl;
        int  wtf[4] = { 666, 888, 999,222 };
        int *pointerWtf;
        pointerWtf = wtf;//数组的变量名就是一个指针,指向了数组首元素
        cout << "pointerWtf[0] == " << pointerWtf[0] << endl;
        pointerWtf++;
        cout << "pointerWtf[0] == " << pointerWtf[0] << endl;
        pointerWtf--;
        cout << "pointerWtf[0] == " << pointerWtf[0] << endl;


        getchar();

        return 0;
    }

输出


    通过指针遍历数组
    Address of var[0] = 0053FB58
    Value of var[0] = 10
    Address of var[1] = 0053FB5C
    Value of var[1] = 100
    Address of var[2] = 0053FB60
    Value of var[2] = 200
    其他一些奇淫技巧
    pointerWtf[0] == 666
    pointerWtf[0] == 888
    pointerWtf[0] == 666

C++指针数组

  • 一般的指针数组就是指的这个数组内存储的元素是指针
  • 然而char类型的指针数组比较特殊,有点懵逼,先TODO后面补上。

    #include <iostream>
    using namespace std;

    void pointerArray();
    void pointerArray4Char();
    void whatCharPointerArray();
    const int MAX = 3;

    int main(void) {

        cout << "********************whatCharPointerArray********************" << endl;
        //char数组,最原始的理解,遇见了问题
        whatCharPointerArray();
        cout << "********************pointerArray********************" << endl;
        //int数组,常规情况,这个打印正常
        pointerArray();
        cout << "********************pointerArray4Char********************" << endl;
        //用一个指向字符的指针数组来存储一个字符串列表
        pointerArray4Char();
        getchar();
        return 0;
    }


    //char数组,最原始的理解,遇见了问题
    void whatCharPointerArray() {

        char charArray[3] = { 'a','b','c' };
        char *pCharArray[3];
        for (int i = 0; i < MAX; i++) {
            pCharArray[i] = &charArray[i];//赋值为整数的地址
        }
        for (int i = 0; i < MAX; i++) {
            cout << "Value of var *pCharArray[" << i << "] = " << *pCharArray[i] << endl;
            cout << "Address of var pCharArray[" << i << "] = " << pCharArray[i] << endl;
        }
    }

    //int数组,常规情况,这个打印正常
    void pointerArray() {
        int var[MAX] = { 20,30,40 };
        int *ptr[MAX];
        for (int i = 0; i < MAX; i++) {
            ptr[i] = &var[i];//赋值为整数的地址
        }
        for (int i = 0; i < MAX; i++) {
            cout << "Value of var *ptr[" << i << "] = " << *ptr[i] << endl;
            cout << "Address of var ptr[" << i << "] = " << ptr[i] << endl;
        }
    }

    /**
    * 用一个指向字符的指针数组来存储一个字符串列表
    * Value of names[0] = sun;
    */
    void pointerArray4Char() {
        const char *names[MAX] = {
            "sun","bin","sunbin"
        };
        for (int i = 0; i < MAX; i++) {
            cout << "Value of names[" << i << "] = ";//输出字符串的值
            cout << names[i] << endl;
            cout << "Value of *names[" << i << "] = ";//输出指针所指向字符串首地址的值
            cout << *names[i] << endl;
            cout << "Value of *names[" << i << "]+1 = ";//输出ascii码值
            cout << *names[i] + 1 << endl;
            cout << "Value of *(names[" << i << "]+1) = ";//输出指针所指向字符串首地址上一位的值
            cout << *(names[i] + 1) << endl;
        }

    }

输出:


    ********************whatCharPointerArray********************
    Value of var *pCharArray[0] = a
    Address of var pCharArray[0] = abc烫烫獭醟3曾
    Value of var *pCharArray[1] = b
    Address of var pCharArray[1] = bc烫烫獭醟3曾
    Value of var *pCharArray[2] = c
    Address of var pCharArray[2] = c烫烫獭醟3曾
    ********************pointerArray********************
    Value of var *ptr[0] = 20
    Address of var ptr[0] = 001CF7EC
    Value of var *ptr[1] = 30
    Address of var ptr[1] = 001CF7F0
    Value of var *ptr[2] = 40
    Address of var ptr[2] = 001CF7F4
    ********************pointerArray4Char********************
    Value of names[0] = sun
    Value of *names[0] = s
    Value of *names[0]+1 = 116
    Value of *(names[0]+1) = u
    Value of names[1] = bin
    Value of *names[1] = b
    Value of *names[1]+1 = 99
    Value of *(names[1]+1) = i
    Value of names[2] = sunbin
    Value of *names[2] = s
    Value of *names[2]+1 = 116
    Value of *(names[2]+1) = u

C++指针的指针

通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。


    #include <iostream>
    //指针的指针
    using namespace std;

    void main() {

        int value = 666;

        int *p = &value;
        int **pp = &p;

        cout << *(*pp) << endl;

        getchar();

    }

输出666;

void*p

在代码过程中常常看见这种定义。一般称为“void指针”。

特点:
1. void指针可以指向任意类型的数据,即可用任意数据类型的指针对void指针赋值。

int *pint;
void *pvoid; //它没有类型,或者说这个类型不能判断出指向对象的长度
pvoid = pint; //只获得变量/对象地址而不获得大小,但是不能 pint =pvoid;

2.如果要将pvoid赋给其他类型指针,则需要强制类型转换如:

pint = (int *)pvoid;  //转换类型也就是获得指向变量/对象大小

3.void指针不能复引用(即取内容的意思)

*pvoid//错误

4.不能对void指针进行算法操作,按照ANSI(AmericanNationalStandardsInstitute)标准,即下列操作都是不合法的:

void* pvoid;
pvoid++;//ANSI:错误
pvoid+=1;//ANSI:错误

5.void不能代表一个真实的变量

void a;                              //错误
function(void a);                     //错误

引用

什么是引用

  • 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。
  • 一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。在代码里用&表示。

引用的作用

  • C++ 支持把引用作为参数传给函数,这比传一般的参数更安全。
  • 可以从 C++ 函数中返回引用,就像返回其他数据类型一样。

引用和指针的区别

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。

示例代码

引用基本使用以及将引用作为参数传递进方法

1.这里我先是定义俩常规变量
2.然后声明了俩引用分别初始化给这俩常规变量
3.通过改变这些值进行观察,得出结论无论该谁谁都跟着变


    #include <iostream>
    using namespace std;
    void changeValue(int & a, double & b);

    //引用 基本使用 和 将引用作为一个参数传递给方法
    void main() {

        // 声明简单的变量
        int    i;
        double d;

        // 声明引用变量
        int&    r = i;
        double& s = d;

        i = 666;
        d = 66.6;

        cout << "Value of r : " << r << endl;
        cout << "Value of s : " << s << endl;

        //-----------------changeValue();---------------
        changeValue(r,s);
        cout << "Value of i : " << i << endl;
        cout << "Value of d : " << d << endl;


        getchar();
    }


    void changeValue(int & a, double & b) {
        cout << "---------changeValue-----------" << endl;
        a = 888;
        b = 888.88;
    }

输出:


    Value of r : 666
    Value of s : 66.6
    ---------changeValue-----------
    Value of i : 888
    Value of d : 888.88

将引用作为返回值返回

引用作为返回值,必须遵守以下规则:
1.不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,程序会进入未知状态。
2.不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一 个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。
3.可以返回类成员的引用,但最好是const。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常 量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

这个程序执行的流程是:
1.定义一个数组作为数据样本
2.setValues方法接收一个int参数作为角标,然后以此为基础去读取定义好的数组
3.读出来的值赋值给本方法内一个引用变量double &temp,然后返回该变量
4.main方法内对返回的引用变量进行操作,观察数据


    #include <iostream>

    using namespace std;

    double vals[] = { 10.1, 12.6, 33.1, 24.1, 50.0 };

    double& setValues(int i)
    {   
        double &temp = vals[i];//将引用指向第i个元素
        return temp;   // 返回第 i 个元素的引用
    }

    // 要调用上面定义函数的主函数
    int main()
    {

        cout << "改变前的值" << endl;
        for (int i = 0; i < 5; i++)
        {
            cout << "vals[" << i << "] = ";
            cout << vals[i] << endl;
        }

        setValues(1) = 20.23; // 改变第 2 个元素
        setValues(3) = 70.8;  // 改变第 4 个元素

        cout << "改变后的值" << endl;
        for (int i = 0; i < 5; i++)
        {
            cout << "vals[" << i << "] = ";
            cout << vals[i] << endl;
        }

        getchar();

        return 0;
    }

C++ 数据结构

  • 为了定义结构,您必须使用 struct 语句。
  • struct 语句定义了一个包含多个成员的新的数据类型。
  • 有点儿对象的意思,跟javaBean有点像。

    #include <iostream>
    #include <cstring>

    using namespace std;

    // 声明一个结构体类型 Books 
    struct Person
    {
        char name[40];
        int age;
    };


    //C++数据结构
    void main() {

        Person zhangsan,lisi;

        strcpy(zhangsan.name, "张三");
        zhangsan.age = 18;

        strcpy(lisi.name, "李四");
        lisi.age = 20;


        cout << "zhangsan name : " << zhangsan.name << endl;
        cout << "zhangsan age : " << zhangsan.age << endl;

        cout << "lisi name : " << lisi.name << endl;
        cout << "lisi age : " << lisi.age << endl;


        getchar();

    }

输出:

zhangsan name : 张三
zhangsan age : 18
lisi name : 李四
lisi age : 20

Demo

本文Demo:https://github.com/zj614android/c-c-/tree/master/Lis4

猜你喜欢

转载自blog.csdn.net/user11223344abc/article/details/80524964