android 源码阅读的C++语法准备3 指针 引用 struct结构

1. 指针

定义指针变量

C 语言中,定义变量时,在变量名 前 写一个 * 星号,这个变量就变成了对应变量类型的指针变量。必要时要加 ( ) 来避免优先级的问题。

引申:C 语言中,定义变量时,在定义的最前面写上 typedef ,那么这个变量名就成了一种类型,即这个类型的同义词。

int a ; //int类型变量 a
int *a ; //int* 变量a
int arr[3]; //arr是包含3个int元素的数组
int (* arr )[3]; //arr是一个指向包含3个int元素的数组的指针变量


//-----------------各种类型的指针------------------------------

int* p_int; //指向int类型变量的指针 

double* p_double; //指向idouble类型变量的指针 

struct Student *p_struct; //结构体类型的指针

int(*p_func)(int,int); //指向返回类型为int,有2个int形参的函数的指针 

int(*p_arr)[3]; //指向含有3个int元素的数组的指针 

int** p_pointer; //指向 一个整形变量指针的指针

取地址

既然有了指针变量,那就得让他保存其它变量的地址,使用 & 运算符取得一个变量的地址。

int add(int a , int b)
{
    return a + b;
}

int main(void)
{
    int num = 97;
    float score = 10.00F;
    int arr[3] = {1,2,3};

    //-----------------------

    int* p_num = #
    float* p_score = &score;
    int (*p_arr)[3] = &arr;           
    int (*fp_add)(int ,int )  = add;  //p_add是指向函数add的函数指针!!
    return 0;
}

特殊的情况,他们并不一定需要使用 & 取地址:

  • 数组名的值就是这个数组的第一个元素的地址。
  • 函数名的值就是这个函数的地址。
  • 字符串字面值常量作为右值时,就是这个字符串对应的字符数组的名称, 也就是这个字符串在内存中的地址。
int add(int a , int b){
    return a + b;
}
int main(void)
{
    int arr[3] = {1,2,3};
    //-----------------------
    int* p_first = arr;
    int (*fp_add)(int ,int )  =  add;
    const char* msg = "Hello world";
    return 0;
}

解地址

我们需要一个数据的指针变量干什么?当然使用通过它来操作(读 / 写)它指向的数据啦。对一个指针解地址,就可以取到这个内存数据,解地址的写法,就是在指针的前面加一个 * 号。
解指针的实质是:从指针指向的内存块中取出这个内存数据。

int main(void)
{
    int age = 19;
    int*p_age = &age;
    *p_age  = 20;  //通过指针修改指向的内存数据

    printf("age = %d\n",*p_age);   //通过指针读取指向的内存数据
    printf("age = %d\n",age);

    return 0;
}

Null 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针,它表明该指针不指向一个可访问的内存位置。

int  *ptr = NULL;
if(ptr)     /* 如果 ptr 非空,则完成 */
if(!ptr)    /* 如果 ptr 为空,则完成 */

指针的算术运算

ptr++会带来什么?
int *ptr : 假设指向地址 1000 的整型指针,是一个 32 位的整数,递增一次后,将指向下一个整数位置,即当前位置往后移 4 个字节,1004
char *ptr : 假设 ptr 指向一个地址为 1000 的字符,递增一次后,将指向下一个字符 1001

指针的比较

指针可以用关系运算符进行比较,如 ==、< 和 >。如果 p1 和 p2 指向两个相关的变量,比如同一个数组中的不同元素,则对 p1 和 p2 进行大小比较是有意义的,否则比较地址值的大小通常没有意义。

指针 vs 数组

指针和数组在很多情况下是可以互换的,但注意不能修改数组名的值

#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
   int  var[MAX] = {10, 100, 200};
   for (int i = 0; i < MAX; i++)
   {
      *var = i;    // 这是正确的语法
      *(var + 2) = i; // 这是正确的语法
      var++;       // 这是不正确的
   }
   return 0;
}

指针的数组

int *ptr[MAX];// ptr 中的每个元素,都是一个指向 int 值的指针
 const char *names[MAX] = {
                   "Zara Ali",
                   "Hina Ali",
                   "Nuha Ali",
                   "Sara Ali",
   };//names 的每一个元素都指向一个char类型的指针,可以存储一个字符串列表

指向指针的指针(多级间接寻址)

int **var;
指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置。

多级间接寻址

2. 引用

引用是某个已存在变量的别名。

引用 vs 指针

  • 不存在空引用。引用必须连接到一块合法的内存。
  • 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
  • 引用必须在创建时被初始化。指针可以在任何时间被初始化。
   // 声明简单的变量
   int    i;
   double d;
 
   // 声明引用变量 "&" 读作引用
   int&    r = i;// r 是一个初始化为 i 的整型引用
   double& s = d;// s 是一个初始化为 d 的 double 型引用

引用作为参数和返回值

通过使用引用来替代指针,会使 C++ 程序更容易阅读和维护

// 把引用作为参数,会改变内存值
void swap(int& x, int& y);

//引用作为返回值,要注意被引用的对象不能超出作用域,返回一个对**局部变量**的引用是不合法的
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )
{
  return vals[i];   // 返回第 i 个元素的引用
}

3. C++ 日期 & 时间

#include <ctime>

四个与时间相关的类型:clock_ttime_tsize_ttm

#include <iostream>
#include <ctime>
using namespace std;
 
int main( )
{
   // 基于当前系统的当前日期/时间
   time_t now = time(0);
   // 把 now 转换为字符串形式
   char* dt = ctime(&now);
   cout << "本地日期和时间:" << dt << endl;
   // 把 now 转换为 tm 结构
   tm *gmtm = gmtime(&now);
   dt = asctime(gmtm);
   cout << "UTC 日期和时间:"<< dt << endl;
}

4. C++ 基本的输入输出

I/O头文件

头文件 函数和描述
<iostream> 该文件定义了 cin、cout、cerrclog 对象,分别对应于标准输入流标准输出流、非缓冲标准错误流和缓冲标准错误流。
<iomanip> 该文件通过所谓的参数化的流操纵器(比如 setwsetprecision),来声明对执行标准化 I/O 有用的服务。
<fstream> 该文件为用户控制的文件处理声明服务。

iostream

#include <iostream>
 
using namespace std;
 
int main( )
{
   char name[50];
   cout << "请输入您的名称: ";//<< 运算符被重载来输出内置类型(整型、浮点型、double 型、字符串和指针)的数据项
   cin >> name; //cin >> name >> age;相当于cin >> name; cin >> age;
   cout << "您的名称是: " << name << endl;
   char str[] = "Unable to read....";
  //标准错误流
   cerr << "Error message : " << str << endl;//附属到标准错误设备,通常也是显示屏
  //标准日志流
  clog << "Error message : " << str << endl;
}

5. Struct 结构

struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;

使用成员访问运算符(.)访问

结构作为函数参数

可以把结构作为函数参数,传参方式与其他类型的变量或指针类似

指向结构的指针

可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似

struct Books *struct_pointer;
struct_pointer->title;//使用 -> 运算符,指向该结构的指针 的成员

typedef 关键字

是一种更简单的定义结构的方式,可以为创建的类型取一个"别名"

typedef struct
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Books;
typedef long int *pint32;

Books Book1, Book2;
pint32 x, y, z;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容

  • void* 类型指针:通用变体类型指针;可以不经转换,赋给其他指针,函数指针除外;malloc返回的就是void*...
    冰吉凌阅读 3,304评论 0 18
  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,422评论 3 44
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,500评论 1 51
  • api.HN_ITEM_ENDPOINT+topStoryIDs[startIndex]+".json"-----...
    Cola1993a阅读 581评论 0 0
  • 今天查技术点逛论坛的时候偶然打开了一篇简书的技术文章,想起第一次来简书的时候还是16年的5/6月份,简书给我感觉就...
    韩世杰的简述阅读 122评论 0 0