c++指針,引用,日期,輸入輸出和數據結構

1,指針

指針是一個變量,其值爲另外一個變量的地址,即,內存位置的直接地址。就像其餘變量或常量同樣,您必須在使用指針存儲其餘變量地址以前,對其進行聲明。指針變量聲明的通常形式爲:html

int    *ip;    /* 一個整型的指針 */
double *dp;    /* 一個 double 型的指針 */
float  *fp;    /* 一個浮點型的指針 */
char   *ch;    /* 一個字符型的指針 */

指針的大小是同樣的,都是一個表明內存地址的長的十六進制數。不一樣數據類型的指針之間惟一的不一樣是,指針所指向的變量或常量的數據類型不一樣。前端

指針使用實例:python

#include <iostream>
using namespace std;
int main ()
{
int var = 20; // 實際變量的聲明
int *ip; // 指針變量的聲明,只聲明未初始化
ip = &var; // 初始化,在指針變量中存儲 var 的地址
cout << "Value of var variable: ";
cout << var << endl;    //原變量的值是20
// 輸出在指針變量中存儲的地址
cout << "Address stored in ip variable: ";
cout << ip << endl;    //輸出的是存儲的地址,是地址
// 訪問指針中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;    //加×之後輸出的是地址區域對應的內容是值,這叫指針
return 0;
}

指針能夠爲空:ios

在變量聲明的時候,若是沒有確切的地址能夠賦值,爲指針變量賦一個 NULL 值是一個良好的編程習慣。賦爲 NULL 值的指針被稱爲指針。c++

#include <iostream>

using namespace std;

int main ()
{
   int  *ptr = NULL;

   cout << "ptr 的值是 " << ptr ;
 
   return 0;
}

指針的可變的:可加可減編程

#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
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++;    //指針指向的內存地址是能夠經過計算改變的,我估計用的是類似數據存儲位置相近原理
}
return 0;
}

產生的結果以下:數組

Address of var[0] = 0x7ffe3c8e3980
Value of var[0] = 10
Address of var[1] = 0x7ffe3c8e3984
Value of var[1] = 100
Address of var[2] = 0x7ffe3c8e3988
Value of var[2] = 200數據結構

 指針能夠比較大小:dom

#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr;
// 指針默認指向的是數組中的第一個元素,第一個元素的地址,而不是整個數組
ptr = var;
int i = 0;
while ( ptr <= &var[MAX - 1] )    //指針只要比var[2]小就繼續向下移動
{
cout << "Address of var[" << i << "] = ";
cout << ptr << endl;
cout << "Value of var[" << i << "] = ";
cout << *ptr << endl;
// 指向上一個位置
ptr++;    //指針向下一個元素移動,數組中的內存地址是有講究的,它們按順序排列,因此能夠經過++的方式獲取下一個元素
i++;
}
return 0;
}

指針數組:編程語言

我的以爲指針數組有兩種,一種是建立一個數組用以存儲多個指針,以下:

#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
int var[MAX] = {10, 100, 200};
int *ptr[MAX];    //建立一個指針數組,長度爲3
for (int i = 0; i < MAX; i++)
{
ptr[i] = &var[i]; // 把指針數組中的元素挨個賦值爲var數組中元素的地址
}
for (int i = 0; i < MAX; i++)    //遍歷指針數組,取值輸出
{
cout << "Value of var[" << i << "] = ";
cout << *ptr[i] << endl;
}
return 0;
}


返回:
Value of var[0] = 10 Value of var[1] = 100 Value of var[2] = 200
 

另外一個是建立一個數組不存儲值,而是存儲值存放的內存位置:

#include <iostream>
using namespace std;
const int MAX = 4;
int main ()
{
const char *names[MAX] = {    //聲明而且初始化一個指針數組
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali",
};
for (int i = 0; i < MAX; i++)
{
cout << "Value of names[" << i << "] = ";
cout << names[i] << endl;    //此處要注意,上一個例子打印出內存地址對應的值用的是:*數組名[索引號],而此處不能這樣用,緣由不明,可是若是用*name[i]打印出來的將會是ZHNS,首字母,大約是由於指針指向數組的首個吧,可是name[i]爲什麼能打印出值來,就不得而知了
}
return 0;
}


返回
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali

指針能夠指向指針:

聲明:

int **var;

實例:

#include <iostream>
using namespace std;
int main ()
{
int var;
int *ptr;
int **pptr;
var = 3000;
// 獲取 var 的地址
ptr = &var;
// 使用運算符 & 獲取 ptr 的地址
pptr = &ptr;
// 使用 pptr 獲取值
cout << "var 值爲 :" << var << endl;   //3000
cout << "*ptr 值爲:" << *ptr << endl;    //3000
cout << "**pptr 值爲:" << **pptr << endl;    //3000
return 0;
}

指針傳遞給函數:

只要聲明函數的時候說明是指針就能夠了

#include <iostream>
#include <ctime>
using namespace std;
void getSeconds(unsigned long *par);    //聲明瞭是無符號常整型的指針,也能夠傳遞數組,
int main ()
{
unsigned long sec;
getSeconds( &sec );    //用的時候傳遞進去的是地址
// 輸出實際值
cout << "Number of seconds :" << sec << endl;
return 0;
}
void getSeconds(unsigned long *par)
{
// 獲取當前的秒數
*par = time( NULL );    //實際參數會被改變
return;
}

返回:
Number of seconds :1294450468

從函數返回指針:

首先要定義一個返回指針的函數,其次要知道,c++不支持返回純局部變量,除非局部變量爲static

#include <iostream>
#include <ctime>
#include <cstdlib>
 
using namespace std;
 
// 要生成和返回隨機數的函數
int * getRandom( )
{
  static int  r[10];
 
  // 設置種子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)    //數組是長度爲10的int數組
  {
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// 要調用上面定義函數的主函數
int main ()
{
   // 一個指向整數的指針,由於返回的是指針因此返回的值也必須由指針存儲
   int *p;
 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )    //數組打印出第一個來就好了
   {
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;    
   }
 
   return 0;
}

2,引用

引用約等於淺拷貝,是原來的變量的別名,因此引用不能爲空,引用不能改變,引用必須在建立的時候被初始化,函數不能返回一個局部變量的引用,static例外

好比:

int i = 17;
int&  r = i;
//r 是一個初始化爲 i 的整型引用

實例:

#include <iostream>
using namespace std;
int main ()
{
// 聲明簡單的變量
int i;
double d;
// 聲明引用變量,引用不可爲空說的是引用必須是某個變量的別名
int& r = i;
double& s = d;
i = 5;   
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}

函數返回一個引用實例:

#include <iostream>
using namespace std;
double vals[] = {10.1, 12.6, 33.1, 24.1, 50.0};
double& setValues( int i )    //從函數的聲明和初始化就能看出來這個函數要返回的是個引用
{
return vals[i]; // 返回第 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;
}
return 0;
}

返回:
改變前的值 vals[0] = 10.1 vals[1] = 12.6 vals[2] = 33.1 vals[3] = 24.1 vals[4] = 50 改變後的值 vals[0] = 10.1 vals[1] = 20.23 vals[2] = 33.1 vals[3] = 70.8 vals[4] = 50

引用也能夠做爲參數:

聲明函數的時候這樣作就能夠了:

void swap(int& x, int& y);

3,日期和時間

c++比c多了處理日期和時間的相關函數和結構,可引用<ctime>,有四個與時間相關的類型:clock_t、time_t、size_t 和 tm

 

序號 函數 & 描述
1 time_t time(time_t *time);
該函數返回系統的當前日曆時間,自 1970 年 1 月 1 日以來通過的秒數。若是系統沒有時間,則返回 .1。
2 char *ctime(const time_t *time);
該返回一個表示當地時間的字符串指針,字符串形式 day month year hours:minutes:seconds year\n\0
3 struct tm *localtime(const time_t *time);
該函數返回一個指向表示本地時間的 tm 結構的指針。
4 clock_t clock(void);
該函數返回程序執行起(通常爲程序的開頭),處理器時鐘所使用的時間。若是時間不可用,則返回 .1。
5 char * asctime ( const struct tm * time );
該函數返回一個指向字符串的指針,字符串包含了 time 所指向結構中存儲的信息,返回形式爲:day month date hours:minutes:seconds year\n\0。
6 struct tm *gmtime(const time_t *time);
該函數返回一個指向 time 的指針,time 爲 tm 結構,用協調世界時(UTC)也被稱爲格林尼治標準時間(GMT)表示。
7 time_t mktime(struct tm *time);
該函數返回日曆時間,至關於 time 所指向結構中存儲的時間。
8 double difftime ( time_t time2, time_t time1 );
該函數返回 time1 和 time2 之間相差的秒數。
9 size_t strftime();
該函數可用於格式化日期和時間爲指定的格式。

實例來一波:

#include <iostream>
#include <ctime>
 
using namespace std;
 
int main( )
{
   // 基於當前系統的當前日期/時間,time_t是ctime中相似於數據類型的一種結構,而time()返回的是1990年至今有多少秒
   time_t now = time(0);
   
   // 把 now 轉換爲字符串形式,字符串dt是對時間now的一種引用
   char* dt = ctime(&now);
 
   cout << "本地日期和時間:" << dt << endl;
 
   // 把 now 轉換爲 tm 結構
   tm *gmtm = gmtime(&now);    //這個看起來是指針,函數返回一個指向time的指針
   dt = asctime(gmtm);    //聽說是格林尼治的時間
   cout << "UTC 日期和時間:"<< dt << endl;
}

輸出格式化的當前時間:

//這個徹底看不懂

#include <iostream>
#include <ctime>
#include <stdlib.h>
#include <stdio.h>

using namespace std;

string  Get_Current_Date();

int main( )
{
    // 將當前日期以 20** - ** - ** 格式輸出
    cout << Get_Current_Date().c_str() << endl;

    getchar();
    return 0;
}

string  Get_Current_Date()
{
    time_t nowtime;  
    nowtime = time(NULL); //獲取日曆時間   
    char tmp[64];   
    strftime(tmp,sizeof(tmp),"%Y-%m-%d %H:%M:%S",localtime(&nowtime));   
    return tmp;
}

 4,輸入和輸出

I/O庫重要的頭文件:

頭文件 函數和描述
<iostream> 該文件定義了 cin、cout、cerr 和 clog 對象,分別對應於標準輸入流、標準輸出流、非緩衝標準錯誤流和緩衝標準錯誤流。
<iomanip> 該文件經過所謂的參數化的流操縱器(好比 setw 和 setprecision),來聲明對執行標準化 I/O 有用的服務。
<fstream> 該文件爲用戶控制的文件處理聲明服務。咱們將在文件和流的相關章節討論它的細節。

標準輸出流:cout

#include <iostream>
using namespace std;
int main( )
{
char str[] = "Hello C++";
cout << "Value of str is : " << str << endl;
}

標準輸入流:

#include <iostream>
using namespace std;
int main( )
{
char name[50];
cout << "請輸入您的名稱: ";
cin >> name;    //用戶的輸入賦值給name,相似於python的input
cout << "您的名稱是: " << name << endl;
}

標準錯誤流:cerr 對象是非緩衝的,且每一個流插入到 cerr 都會當即輸出。不大明白用法,且先看吧

#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
cerr << "Error message : " << str << endl;
}

標準日誌流:clog 對象是緩衝的。這意味着每一個流插入到 clog 都會先存儲在緩衝在,直到緩衝填滿或者緩衝區刷新時纔會輸出。

#include <iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
clog << "Error message : " << str << endl;
}

良好的編程實踐告訴咱們,使用 cerr 流來顯示錯誤消息,而其餘的日誌消息則使用 clog 流來輸出。

5,數據結構

C/C++ 數組容許定義可存儲相同類型數據項的變量,可是結構是 C++ 中另外一種用戶自定義的可用的數據類型,它容許您存儲不一樣類型的數據項。

可用struct定義結構,如下是結構實例:

struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
//聲明一個結構體類型 Books,變量爲 book:

用英文點號訪問結構成員,

#include <iostream>
#include <cstring>
using namespace std;
// 聲明一個結構體類型 Books 
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 詳述
strcpy( Book1.title, "C++ 教程");    //strcpy字符串拷貝命令,把第二個字符串的值賦值給第一個,至關於給books結構的book1實例的第一個屬性----title賦值爲‘c++教程’
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 詳述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技術");
Book2.book_id = 12346;
// 輸出 Book1 信息
cout << "第一本書標題 : " << Book1.title <<endl;    //輸出的時候基本格式是實例加.加結構內容
cout << "第一本書做者 : " << Book1.author <<endl;
cout << "第一本書類目 : " << Book1.subject <<endl;
cout << "第一本書 ID : " << Book1.book_id <<endl;
// 輸出 Book2 信息
cout << "第二本書標題 : " << Book2.title <<endl;
cout << "第二本書做者 : " << Book2.author <<endl;
cout << "第二本書類目 : " << Book2.subject <<endl;
cout << "第二本書 ID : " << Book2.book_id <<endl;
return 0;
}

結構做爲函數的參數:

#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books book );    //聲明一個函數,參數是結構
// 聲明一個結構體類型 Books 
struct Books    
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 內容賦值
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 內容賦值
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技術");
Book2.book_id = 12346;
// 輸出 Book1 信息
printBook( Book1 );    //直接把結構傳遞進去就好了,不用加struct
// 輸出 Book2 信息
printBook( Book2 );
return 0;
}
void printBook( struct Books book )    //函數實現
{
cout << "書標題 : " << book.title <<endl;
cout << "書做者 : " << book.author <<endl;
cout << "書類目 : " << book.subject <<endl;
cout << "書 ID : " << book.book_id <<endl;
}

指向結構的指針:

#include <iostream>
#include <cstring>
using namespace std;
void printBook( struct Books *book );    //函數聲明,聲明須要一個結構的實例的指針
struct Books    //預約義結構的內容
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定義結構體類型 Books 的變量 Book1
Books Book2; // 定義結構體類型 Books 的變量 Book2
// Book1 詳述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "編程語言");
Book1.book_id = 12345;
// Book2 詳述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技術");
Book2.book_id = 12346;
// 經過傳 Book1 的地址來輸出 Book1 信息
printBook( &Book1 );    //由於須要的是指針,因此要把book1 book2 的內存地址放進去
// 經過傳 Book2 的地址來輸出 Book2 信息
printBook( &Book2 );
return 0;
}
// 該函數以結構指針做爲參數
void printBook( struct Books *book )
{
cout << "書標題 : " << book->title <<endl;    //此處要特別注意,訪問指針指向的實例中的結構內容的話,不能繼續用點號了,要用->號,不用問爲啥,由於是規定
cout << "書做者 : " << book->author <<endl;
cout << "書類目 : " << book->subject <<endl;
cout << "書 ID : " << book->book_id <<endl;
}

補充typedef:

typedef爲C語言的關鍵字,做用是爲一種數據類型定義一個新名字。這裏的數據類型包括內部數據類型(int,char等)和自定義的數據類型(struct等)。在編程中使用typedef目的通常有兩個,一個是給變量一個易記且意義明確的新名字,另外一個是簡化一些比較複雜的類型聲明。

//(1)用typedef聲明一個新類型名來代替已有的類型名。如
typedef int Status  //指定標識符Status表明int類型
typedef double DATE  //指定標識符DATE表明double類型
int i; Status i;    //等價的

//(2)用typedef對數組類型起新名:
typedef int NUM[100];//聲明NUM爲整數數組類型,能夠包含100個元素
NUM n;//定義n爲包含100個整數元素的數組,n就是數組名

//(3)對一個結構體類型聲明一個新名字:
typedef struct  //在struct以前用了關鍵字typedef,表示是聲明新類型名
{
    int month;
    int day;
    int year;  
} TIME; //TIME是新類型名,但不是新類型,也不是結構體變量名,這樣就能夠用TIME定義該結構體變量,如:
TIME birthday;
//不用typeof的時候:
struct Books    //Books是結構體類型
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;    //book是結構變量
相關文章
相關標籤/搜索