起步
// C++向下兼容C,在練習(xí)過(guò)程中,請(qǐng)將代碼保存為.cpp文件
/*
* 頭文件
* 1. ".h"為頭文件的文件格式
* 2. C++等價(jià)寫法:#include <cstdio>
*/
#include <stdio.h>
/*
* 主函數(shù)
* 1. 程序入口
* 2. 程序從主函數(shù)開始執(zhí)行
* 3. 一個(gè)程序最多只能有一個(gè)主函數(shù)
*/
int main(){
int a,b;
scanf("%d%d",&a,&b);
printf("%d",a+b);
return 0;
}
一、基本數(shù)據(jù)類型
變量類型
整型
常用整型(int)和長(zhǎng)整型(long long)。
說(shuō)明:
- 絕對(duì)值在109范圍以內(nèi)的整數(shù)都能定義成int型。
- 如果給long long型賦一個(gè)大于231-1的初值,請(qǐng)?jiān)跀?shù)字后加LL。如:long long bigNum = 1234567890123345LL。
- 題目要求109以內(nèi)或32位整數(shù)時(shí),用int存放;若是1018以內(nèi)(如1010)或者說(shuō)64位整數(shù),使用long long存放。
浮點(diǎn)型
浮點(diǎn)型就是小數(shù),氛圍單精度(float)和雙精度(double)。
說(shuō)明:
- float有效精度6~7位,少用。
- 碰到浮點(diǎn)型的數(shù)據(jù)使用double來(lái)存儲(chǔ)。
字符型
說(shuō)明:
- C語(yǔ)言中,字符常量統(tǒng)一使用ASCII碼統(tǒng)一編碼(范圍0~127)。
- 小寫字母比大寫字母的ASCII碼值大32(a->97,A->65,空格->32)。
- 字符常量(必須是單個(gè)字符)必須使用單引號(hào)標(biāo)注('z','h','r')。
- 可以將整數(shù)的ASCII碼值賦給字符變量,因?yàn)樵谟?jì)算機(jī)內(nèi)部,字符就是按ASCII碼存儲(chǔ)的。
- 轉(zhuǎn)義字符"\0"代表空字符NULL(注意不是空格),其ASCII碼為0。
字符串常量
#include <cstdio>
int main(){
/*
* 字符數(shù)組
* 1. 字符串常量為""標(biāo)記的字符集。
* 2. 不能把字符串常量賦值給字符變量(不允許char c = "zhanghaoran";)
* 3. 字符串常量可以作為初值賦值給字符數(shù)組,使用%s的格式輸出。
*/
char str[50] = "2022,kaoyanbisheng!";
printf("%s",str);
return 0;
布爾型
#include <cstdio>
int main(){
bool flag1 = 10;
bool flag2 = -10;
bool flag3 = 0;
printf("%d\n%d\n%d",flag1,flag2,flag3);
/**
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1
1
0
Process finished with exit code 0
*/
return 0;
}
說(shuō)明:
- 布爾型(bool)在cpp文件中直接使用,在C語(yǔ)言中要添加stdbool.h頭文件才能使用。
- 給布爾型變量賦值的時(shí)候可以使用true、false或者整型常量。整型常量在賦值給bool變量時(shí),會(huì)自動(dòng)轉(zhuǎn)換成true(非0)和false(0)。
- bool中,true使用1存儲(chǔ),false使用0存儲(chǔ),%d打印時(shí)會(huì)輸出數(shù)字。
常量定義
常用的定義常量的方式有兩種:
#define PI 3.1415 // 宏定義
const double PI = 3.1415; // const關(guān)鍵字
二、順序結(jié)構(gòu)
scanf與printf
#include <cstdio>
int main(){
/*
n = n + 2 <=> n += 2 后者稱為符合賦值運(yùn)算符,可以加快編譯速度和提高可讀性,應(yīng)常用這種方式。
*/
int n = 0;
n += 2;
printf("%d",n);
int age;
/* 關(guān)于scanf()
* 1. scanf("格式控制",變量地址)
* 2. "&"——取地址運(yùn)算符
* 3. 特別的數(shù)據(jù)類型變量的scanf格式符:
* - long long: %lld
* - double: %lf
* 4. scanf中,char數(shù)組整個(gè)輸入的情況下不加&,因?yàn)閿?shù)組名稱本身就代表了數(shù)組第一個(gè)元素的地址
* 5. 字符數(shù)組讀入時(shí)以空格和換行符為讀入結(jié)束的標(biāo)志,因此當(dāng)輸入"zhang haoran"想賦值給name時(shí),name只會(huì)保存"zhang"
* 6. scanf的%c格式可以讀入空格和換行。
*/
scanf("%d",&age);
char name[20];
scanf("%s",name);
/*
* 關(guān)于printf():
* 1. 對(duì)于double類型的變量,在printf中的輸出格式為%f,而在scanf中是%lf
* 2. 輸出%和\時(shí),需要轉(zhuǎn)義,即"%%"和"\\"
*/
printf("姓名:%s\n年齡:%d",name,age);
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
20
zhanghaoran
姓名:zhanghaoran
年齡:20
Process finished with exit code 0
*/
// 補(bǔ)充三種常用的輸出格式
{
int num = 720;
// 1. %md 使不足m位的int型變量以m位進(jìn)行右對(duì)齊輸出,高位空格補(bǔ)齊
printf("%5d",num);
// 2. 區(qū)別于%md,%0md高位0補(bǔ)齊
printf("%05d",num);
double d = 1.1234567;
// 3. 讓浮點(diǎn)數(shù)保留m位小數(shù)輸出
printf("%.2f",d);
}
return 0;
}
getchar與putchar
#include <cstdio>
int main(){
char c1,c2,c3;
// 1. getchar()能識(shí)別空格和換行符
// 2. getchar()用來(lái)輸入單個(gè)字符,putchar用來(lái)輸出單個(gè)字符
c1 = getchar();
c2 = getchar();
c3 = getchar();
putchar(c1);
putchar(c2);
putchar(c3);
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
z hr
z h
Process finished with exit code 0
*/
}
typedef
typedef關(guān)鍵字用于給復(fù)雜的一個(gè)數(shù)據(jù)類型取別名。
// 給long long數(shù)據(jù)類型取一個(gè)別名Long
typedef long long Long;
Long l = 123456789LL;
常用的math函數(shù)
在使用數(shù)學(xué)函數(shù)前,要使用<code>#include<math.h></code>引入頭文件。
- fabs(double x)
對(duì)double型變量取絕對(duì)值。- floor(double x) 和 ceil(double x)
對(duì)double型的變量進(jìn)行向下取整和向上取整。- pow(double r,double p)
返回rp- sqrt(double x)
返回double型變量的算數(shù)平方根。- log(double x)
返回double型變量以自然對(duì)數(shù)為底的對(duì)數(shù)- sin(double x)、cos(double x)、tan(double x)
返回對(duì)應(yīng)的三角函數(shù)值,參數(shù)要求是弧度制。- round(double x)
將double型變量x四舍五入后取整然后返回double類型。
三、選擇結(jié)構(gòu)
下面這種寫法在許多數(shù)據(jù)結(jié)構(gòu)算法的書上經(jīng)常出現(xiàn)。
#include "cstdio"
int main(){
int a = 100;
int b = 0;
if(a){
printf("a is not zero!");
} else {
printf("a is zero!");
}
if(!b){
printf("a is zero!");
} else {
printf("a is not zero!");
}
}
技巧
- 在if條件中,如果表達(dá)式是"!=0",可以省略。
- 在if條件中,如果表達(dá)式是"==0",可以省略,然后在表達(dá)式前加取反運(yùn)算符"!"。
四、循環(huán)結(jié)構(gòu)
對(duì)于以下這種寫法:
for(int i = 0; i < 10 ; i ++){
// ···
}
說(shuō)明:
在C語(yǔ)言中是不允許在for語(yǔ)句的表達(dá)式A中定義變量的,但是在C++中可以,因此以上這種寫法需要把文件保存為.cpp后綴才能通過(guò)編譯。
五、數(shù)組
一維數(shù)組初始化
基本方法
#include <cstdio>
int main(){
/*
* 一維數(shù)組初始化
* 1. 數(shù)組對(duì)部分元素進(jìn)行賦值操作,未被賦值的元素默認(rèn)為0。
* 2. 當(dāng)數(shù)組沒(méi)有被賦初值,每個(gè)元素可能是0,也有可能是一個(gè)隨機(jī)數(shù)。
* 3. 如果想給數(shù)組的每一個(gè)元素賦初值0,只需要把第一個(gè)元素賦為0,或者只用一個(gè){}表示:
* a. int nums[10] = {0};
* b. int nums[10] = {};
*/
int nums[10] = {11,22,33,44,55};
for(int i = 0; i < 10 ; i ++){
printf("nums[%d]=%d\n",i,nums[i]);
}
return 0;
/*
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
nums[0]=11
nums[1]=22
nums[2]=33
nums[3]=44
nums[4]=55
nums[5]=0
nums[6]=0
nums[7]=0
nums[8]=0
nums[9]=0
Process finished with exit code 0
*/
}
使用memset對(duì)數(shù)組中每一個(gè)元素賦相同的值
#include "cstdio"
#include "cstring"
#define n 5
int main(){
/*
* 使用memset給數(shù)組賦初值
* 1. 添加string.h頭文件
* 2. memset按字節(jié)賦值
* 3. 一般使用memset賦初值0或-1
*/
int arr[n];
memset(arr,-1,sizeof(arr));
for(int i = 0; i< n; i ++){
printf("%2d ",arr[i]);
}
memset(arr,0,sizeof(arr));
printf("\n");
for(int i = 0; i< n; i ++){
printf("%2d ",arr[i]);
}
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
-1 -1 -1 -1 -1
0 0 0 0 0
Process finished with exit code 0
*/
}
數(shù)組順推
#include <cstdio>
// 數(shù)組遞推包括:
// 1. 順推
// 2. 逆推
int main(){
int nums[10];
scanf("%d",nums);
for(int i = 1; i < 10 ;i ++){
nums[i] = nums[i - 1] * 2;
}
for(int i = 0; i < 10 ;i ++){
printf("nums[%d]=%d\n",i,nums[i]);
}
return 0;
/*
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1
nums[0]=1
nums[1]=2
nums[2]=4
nums[3]=8
nums[4]=16
nums[5]=32
nums[6]=64
nums[7]=128
nums[8]=256
nums[9]=512
Process finished with exit code 0
*/
}
冒泡排序
#include <cstdio>
/*
* 冒泡排序:
* 1. 進(jìn)行若干趟排序,每趟排序?qū)?shù)組元素的最大值移動(dòng)到最右邊
* 2. 當(dāng)剩余元素為0時(shí),排序結(jié)束
*/
const int n = 10;
int main(){
int nums[n] = {1,4,3,2,7,6,5,9,8};
for(int i = 0 ;i < n - 1; i ++){
for(int j = 0; j < n - i - 1; j ++){
if(nums[j] > nums[j + 1]){
int tmp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = tmp;
}
}
}
for(int i = 0; i< n ; i ++){
printf("%d ",nums[i]);
}
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
0 1 2 3 4 5 6 7 8 9
Process finished with exit code 0
*/
}
二維數(shù)組
#include <cstdio>
#define n 3
int main(){
/*
* 二維數(shù)組初始化
*/
int arr[n][n] = {{1,2},{2}};
for(int i = 0; i< n ;i ++){
for(int j = 0; j< n ;j ++){
printf("%02d ",arr[i][j]);
}
printf("\n");
}
/*
* 兩個(gè)三階矩陣對(duì)應(yīng)位置元素相加,并將結(jié)果存放到另外一個(gè)三階矩陣
*/
int a[n][n];
int b[n][n];
int c[n][n];
for(int i = 0; i < n ; i ++){
for(int j = 0; j< n ; j ++){
scanf("%d",&a[i][j]);
scanf("%d",&b[i][j]);
c[i][j] = a[i][j] + b[i][j];
}
}
// for(int i = 0; i < n ; i ++){
// for(int j = 0; j< n ; j ++){
// scanf("%d",&b[i][j]);
// }
// }
// for(int i = 0; i < n ; i ++){
// for(int j = 0; j< n ; j ++){
// c[i][j] = a[i][j] + b[i][j];
// }
// }
for(int i = 0 ;i < n ; i++){
for(int j = 0; j < n ; j ++){
printf("%d ",c[i][j]);
}
printf("\n");
}
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
01 02 00
02 00 00
00 00 00
1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1
10 10 10
10 10 10
10 10 10
Process finished with exit code 0
*/
}
字符數(shù)組
字符數(shù)組的初始化
#include <stdio.h>
int main(){
// 字符數(shù)組初始化方式1——普通數(shù)組初始化方式
char str1[] = {'z','h','r'};
for(int i = 0 ; i < 3 ; i ++){
printf("%c",str1[i]);
}
printf("\n");
// 字符數(shù)組初始化方式2——賦值字符串(僅限初始化)
char str2[] = "zhanghaoran";
for(int i = 0 ; i< 11; i ++ ){
printf("%c",str2[i]);
}
printf("\n");
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
zhr
zhanghaoran
Process finished with exit code 0
*/
}
字符數(shù)組的輸入輸出
#include "cstdio"
int main(){
/*
* 字符數(shù)組輸入輸出方式1——printf()和scanf()
1. scanf()的%c格式能夠識(shí)別空格和換行符并將其輸入
2. %s通過(guò)空格和換行符來(lái)識(shí)別一個(gè)字符串的結(jié)束
3. scanf()在使用%s時(shí),對(duì)應(yīng)數(shù)組名前不用加取地址運(yùn)算符"&"
*/
// char name[20] = {};
// scanf("%s",name);
// printf("%s",name);
/*
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
zhanghaoran
zhanghaoran
Process finished with exit code 0
*/
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
zhang haoran
zhang
Process finished with exit code 0
*/
/*
* 字符數(shù)組輸入輸出方式2——getchar()和putchar()
* 注意:getchar()能識(shí)別空格和換行符
*/
// const int n = 4;
// char twoDimensionArr[n][n];
// for(int i = 0 ; i < n - 1 ;i ++){
// for(int j = 0 ;j < n - 1 ; j ++){
// twoDimensionArr[i][j] = getchar();
// }
// getchar(); // 把輸入中每行末尾的換行符吸收掉
// }
// for(int i = 0 ; i < n - 1; i ++){
// for(int j = 0 ; j < n - 1; j ++){
// putchar(twoDimensionArr[i][j]);
// }
// putchar('\n');
// }
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
^_^
_^_ ^_^
^_^
_^_
^_^
Process finished with exit code 0
*/
/*
* 字符數(shù)組輸入輸出方式3——gets()和puts()
* 說(shuō)明:
* 1. gets()識(shí)別換行符\n作為輸入結(jié)束,scanf()后如要用gets(),需要先用getchar()把換行符吸收掉。
* 2. gets()輸入的字符串可以包含空格
* 3. puts()輸出會(huì)自動(dòng)換行。
*/
// int a = 0;
// char str[20];
// scanf("%d",&a);
// getchar();
// gets(str);
// puts(str);
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1
warning: this program uses gets(), which is unsafe.
zhanghaoran
zhanghaoran
Process finished with exit code 0
*/
// 使用gets()和puts()操作二維數(shù)組
const int row = 3;
char strs[row][20];
for(int i = 0 ; i < row ; i ++ ){
gets(strs[i]);
}
for(int i = 0 ; i < row ; i ++){
puts(strs[i]);
}
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
warning: this program uses gets(), which is unsafe.
zhang
hao
ran
zhang
hao
ran
Process finished with exit code 0
*/
return 0;
}
字符數(shù)組的存放方式
說(shuō)明:
- 在一維數(shù)組(或二維數(shù)組的第二維)末尾都有一個(gè)空字符'\0',表示存放字符串的結(jié)尾。
- '\0'在使用gets()或者scanf()輸入字符串時(shí)會(huì)自動(dòng)添加在輸入的字符串后面,并占用一個(gè)字符位。
- puts()和printf()通過(guò)識(shí)別'\0'作為字符串的結(jié)尾來(lái)輸出的。
- 結(jié)束符'\0'的ASCII值為0,即空字符NULL,占用一個(gè)字符位,因此,在創(chuàng)建一個(gè)字符數(shù)組時(shí),字符數(shù)組的長(zhǎng)度至少要比實(shí)際存儲(chǔ)的字符串的長(zhǎng)度多1。
- 只有char數(shù)組末尾會(huì)加'\0',int等類型的數(shù)組末尾不加。
- '\0'和空格不是一個(gè)東西,它表示空字符NULL,空格的ASCII值為32。
string.h頭文件
string.h頭文件包含了許多用于字符數(shù)組的函數(shù)。
#include "cstdio"
// 引入string.h頭文件
#include "cstring"
/*
* strlen()——用于獲取字符數(shù)組中第一個(gè)'\0'前的字符的個(gè)數(shù)。
* 格式:strlen(字符數(shù)組)
*/
void strlen_test(){
char str[20];
// gets()可以輸入包含空格的字符串
gets(str);
int len = strlen(str);
printf("%d",len);
printf("\n");
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
warning: this program uses gets(), which is unsafe.
zhang hao ran
13
Process finished with exit code 0
*/
}
/*
* strcmp()——以字典序?yàn)楸容^原則,返回兩個(gè)字符串大小的比較結(jié)果。
* 格式:strcmp(字符數(shù)組1,字符數(shù)組2)
* 說(shuō)明:
* 1. 若字符數(shù)組1<字符數(shù)組2,則返回一個(gè)負(fù)整數(shù)(不一定是-1)。
* 2. 若字符數(shù)組1=字符數(shù)組2,則返回0。
* 3. 若字符數(shù)組1>字符數(shù)組2,則返回一個(gè)正整數(shù)(不一定是1)。
*/
void strcmp_test(){
char str1[30];
char str2[30];
gets(str1);
gets(str2);
int res = strcmp(str1,str2);
if(res < 0){
printf("str1 < str2\n");
}else if(res == 0){
printf("str1 = str2\n");
}else{
printf("str1 > str2\n");
}
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
warning: this program uses gets(), which is unsafe.
nanchang
beijing
str1 > str2
Process finished with exit code 0
*/
}
/*
* strcpy()——把第二個(gè)字符串復(fù)制給第一個(gè)字符串,包括結(jié)束符"\0"
* 格式:strcpy(字符數(shù)組1,字符數(shù)組2)
*/
void strcpy_test(){
char str1[30];
char str2[30];
gets(str2);
strcpy(str1,str2);
puts(str1);
/*
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
warning: this program uses gets(), which is unsafe.
zhanghaoran
zhanghaoran
Process finished with exit code 0
*/
}
/*
* strcat()——把字符串2拼接到字符串1的后面
* 格式:strcat(字符數(shù)組1,字符數(shù)組2)
*/
void strcat_test(){
char str1[30];
char str2[30];
gets(str1);
gets(str2);
strcat(str1,str2);
puts(str1);
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
warning: this program uses gets(), which is unsafe.
zhanghaoran
like coding!
zhanghaoran like coding!
Process finished with exit code 0
*/
}
int main(){
// strlen_test();
// strcmp_test();
// strcpy_test();
strcat_test();
return 0;
}
sscanf()和sprintf()
sscanf()和sprintf()屬于stdio.h頭文件下的函數(shù),用于處理字符串,可以理解為"string+scanf"和"string+printf"。
#include "cstdio"
#include "cstring"
int main(){
char str[10] = "1234";
int num;
sscanf(str,"%d",&num);
printf("%d\n",num);
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1234
Process finished with exit code 0
*/
num = 12345;
sprintf(str,"%d",num);
for(int i = 0 ; i < strlen(str); i ++){
printf("%c ", str[i]);
}
printf("\n");
// printf("%s\n",str);
/*
/Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1234
1 2 3 4 5
Process finished with exit code 0
*/
return 0 ;
}
理解:
- 我們常寫的scanf()和printf()可以寫成:
scanf(screen,"%d",&n); printf(screen,"%d",n);這里的screen就看成是電腦屏幕。scanf的輸入其實(shí)就是把screen中的內(nèi)容以%d的格式傳到變量n中(從左到右);而printf的輸出就是把變量n中的內(nèi)容以"%d"的格式傳到screen。
- 類比到sscanf和sprintf,唯一的改變就是把screen換成了字符數(shù)組,使用格式如下:
char str[20]; sscanf(str,"%d",&n); sprintf(str,"%d",n);
- sprintf()也可以做字符串的復(fù)制
#include "cstdio" int main(){ char str1[20]; char str2[20] = "zhanghaoran"; sprintf(str1,"%s",str2); puts(str1); return 0; /* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled zhanghaoran Process finished with exit code 0 */ }
- sscanf支持正則表達(dá)式
六、函數(shù)
再談main函數(shù):
int main(){
//···
return 0;
}
說(shuō)明:
- 主函數(shù)對(duì)于一個(gè)程序來(lái)說(shuō)只能有一個(gè),無(wú)論主函數(shù)寫在哪個(gè)位置,整個(gè)程序一定是從主函數(shù)的第一個(gè)語(yǔ)句開始執(zhí)行,然后在需要調(diào)用其他函數(shù)的時(shí)候才回去調(diào)用。
- main函數(shù)返回0的意義在于告知系統(tǒng)程序正常終止。
七、指針
指針的相關(guān)概念
變量的存放:
- 變量存放在內(nèi)存中。
- 每個(gè)字節(jié)都會(huì)有一個(gè)地址。
- 計(jì)算機(jī)通過(guò)地址找到某個(gè)變量。
- 變量的地址指的是它占用的字節(jié)中的第一個(gè)字節(jié)的地址。
指針:
- 在計(jì)算機(jī)中,一個(gè)地址"指向"一個(gè)變量,可以通過(guò)地址來(lái)找到變量。
- 在C語(yǔ)言中,使用"指針"表示內(nèi)存地址(或稱指針指向了內(nèi)存地址)。
- 如果一個(gè)指針指向的內(nèi)存地址恰好是某個(gè)變量的地址,就稱"這個(gè)指針指向了該變量"。
- "&"為取地址運(yùn)算符,在變量前加上"&",就表示變量的地址。
- 指針是一個(gè)unsigned類型的整數(shù)。
指針變量
指針變量用于存放指針(或者說(shuō)地址)。
指針變量的定義與初始化
// 1. 數(shù)據(jù)類型后加"*"
int* p;
double* p;
char* p;
// 說(shuō)明:"*"的位置在數(shù)據(jù)類型后或者變量名稱之前都OK的,編譯器不會(huì)對(duì)此進(jìn)行區(qū)分。
//2. 同時(shí)定義多個(gè)指針變量
int *a,*b,*c;
//3. 以下方式只有p1會(huì)被定義為指針類型,p2不會(huì)
int* p1,p2;
//4. 給指針變量賦值的方式一般是把變量的地址使用取地址運(yùn)算符"&"取出后賦值給對(duì)應(yīng)類型的指針變量。
int a = 10;
int* pa = &a;
說(shuō)明:
- int* 才是指針變量的類型,而后面的p才是變量名,用來(lái)存儲(chǔ)變量的地址值。
- 地址值&a是賦值給p而不是*p的。
- 請(qǐng)記住,對(duì)指針變量來(lái)說(shuō),星號(hào)"*"是類型的一部分。
獲取地址所指的元素:
- 在指針變量前加"*"。
- 指針變量p表示的是地址,*p是這個(gè)地址中存放的內(nèi)容。
- 對(duì)指針變量來(lái)說(shuō),把其存儲(chǔ)的地址的類型稱為基類型。
指針與數(shù)組
#include "cstdio"
int main(){
// 1. C語(yǔ)言中,數(shù)組名稱也作為數(shù)組的首地址使用。
// int a[5] = {1};
// int* pa = a;
// printf("%d",*pa);
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
1
Process finished with exit code 0
*/
// 2. 使用指針對(duì)數(shù)組進(jìn)行賦值和遍歷輸出
const int n = 10;
int a[n];
for( int i = 0; i< n;i ++ ){
scanf("%d",a+i);
}
// 遍歷方式1
// for(int i = 0 ; i < n ; i ++){
// printf("%d ",*(a+i));
// }
// printf("\n");
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
Process finished with exit code 0
*/
// 遍歷方式2
for(int* pa = a ; pa < a+n ; pa ++){
printf("%d ",*pa);
}
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
9 8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1 0
Process finished with exit code 0
*/
return 0;
}
在函數(shù)參數(shù)中使用指針
#include "cstdio"
void swap(int* a, int * b){
int tmp = *a;
*a = *b;
*b = tmp;
}
int main(){
int a = 10;
int b = 20;
swap(&a,&b);
printf("%d %d",a,b);
return 0;
}
引用
#include "stdio.h"
void change1(int x){
x = 10;
}
// 形參為引用
void change2(int &x){
x = 10;
}
int main(){
int x = 0 ;
change1(x);
printf("%d\n",x);
change2(x);
printf("%d\n",x);
return 0 ;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
0
10
Process finished with exit code 0
*/
}
關(guān)于引用:
- 引用是C++中的語(yǔ)法,文件必須保存為.cpp類型。
- 引用不產(chǎn)生副本,只是給原變量取了一個(gè)別名,對(duì)引用變量的操作就是對(duì)原變量的操作。
- 使用方法:在函數(shù)的參數(shù)名前加"&"(或者參數(shù)類型之后,因?yàn)橐檬莿e名的意思,所以一般加在變量名前面)
- 不管是否使用引用,函數(shù)的參數(shù)名(形參名)和實(shí)際傳入的參數(shù)名(實(shí)參名)可以不同。
- 注意:把引用的"&"和取地址符"&"區(qū)分開,引用不是取地址的意思,它是C++中的一種語(yǔ)法。
- 強(qiáng)調(diào):由于引用是產(chǎn)生變量的別名,因此常量不可使用引用。
下面是swap方法的另一種實(shí)現(xiàn)方式,這里使用到了指針的引用:
#include "cstdio"
void swap(int* &pa,int* &pb){
int* tmp = pa;
pa = pb;
pb = tmp;
}
int main(){
int a = 10, b = 20;
int *pa = &a;
int *pb = &b;
printf("%d %d\n",*pa,*pb);
swap(pa,pb);
printf("%d %d\n",*pa,*pb);
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
10 20
20 10
Process finished with exit code 0
*/
}
八、結(jié)構(gòu)體
定義結(jié)構(gòu)體的基本格式:
struct struct_name{
// 一些基本的數(shù)據(jù)結(jié)構(gòu)或者自定義的數(shù)據(jù)類型
};
結(jié)構(gòu)體變量和結(jié)構(gòu)體數(shù)組的2種定義方式:
// 方式1
struct studentInfo{
int id;
char gender;
char name[20];
char major[20];
}ZHANGHAORAN,stu[38];
// 方式2
struct studentInfo{
int id;
char gender;
char name[20];
char major[20];
};
studentInfo ZHANGHAORAN;
studentInfo stu[38];
結(jié)構(gòu)體元素的訪問(wèn):
說(shuō)明:
結(jié)構(gòu)體內(nèi)部可以定義除了自己本身的任意數(shù)據(jù)類型(定義自己本身會(huì)引起循環(huán)定義問(wèn)題),但是可以定義自身類型的指針變量。
struct studentInfo{
int id;
char gender;
char name[20];
studentInfo* next;
}stu,*p;
// 結(jié)構(gòu)體普通變量訪問(wèn)結(jié)構(gòu)體內(nèi)部元素
stu.id
stu.name
stu.next
// 結(jié)構(gòu)體指針變量訪問(wèn)結(jié)構(gòu)體內(nèi)部元素
// 說(shuō)明:方式1和方式2等價(jià)
// 方式1
(*p).id
(*p).name
(*p).next
// 方式2
p->id
p->name
p->next
結(jié)構(gòu)體的初始化:
這里介紹結(jié)構(gòu)體的構(gòu)造函數(shù):
struct studentInfo{
int id;
char gender;
char name[20];
// 默認(rèn)構(gòu)造函數(shù),在定義了新的構(gòu)造函數(shù)后被覆蓋,如需使用要單獨(dú)定義。
studentInfo(){}
// 自定義構(gòu)造函授
// 方式1
studentInfo(int _id,char* _name){
id = _id;
name = _name;
}
// 方式2 簡(jiǎn)化版
studentInfo(int _id,char _gender, char* _name):id(_id),gender(_gender),name(_name){
}
};
實(shí)例:
#include "cstdio"
struct Point{
int x;
int y;
Point(){}
Point(int _x,int _y):x(_x),y(_y){}
};
Point pt[10];
int main(){
for(int i = 0 ;i < 10; i ++ ){
pt[i] = Point(i+1,i+1);
}
for(int i = 0 ; i < 10 ; i ++){
printf("(%d,%d) ",(*(pt+i)).x,(*(pt+i)).y);
}
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
(1,1) (2,2) (3,3) (4,4) (5,5) (6,6) (7,7) (8,8) (9,9) (10,10)
Process finished with exit code 0
*/
}
九、補(bǔ)充
cin與cout(不建議使用)
cin和cout是C++中的輸入與輸出函數(shù),需要添加頭文件<code>#include<iostream></code>和<code>using namespace std;</code>后才能使用。
#include "iostream"
using namespace std;
int main(){
char name[20];
int age;
char gender;
char desc[200]={};
/* cin函數(shù):
* 1. cin采用輸入運(yùn)算符">>"進(jìn)行輸入,輸入不用指定格式,也不需要加取地址運(yùn)算符"&"。
* 2. cin可同時(shí)讀入多個(gè)變量,只需往后面使用>>進(jìn)行擴(kuò)展即可。
* 3. 當(dāng)需要讀入一整行時(shí),可以使用cin.getline()函數(shù)
*/
cin >> name >> age >> gender;
getchar(); // 吸收換行符
cin.getline(desc, 200);
/*
* cout函數(shù):
* 1. 使用方法和cin幾乎一致,只不過(guò)使用的是輸出運(yùn)算符"<<"。
* 2. 兩種換行方式:
* a. "\n"
* b. endl(means 'end of line')
*/
cout<<"name:"<<name<<"\n"<<"age:"<<age<<"\n"<<"gender:"<<gender<<"\n"<<"desc:"<<desc<<endl;
return 0 ;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
zhanghaoran
20
M
The monitor of class 1821801z
name:zhanghaoran
age:20
gender:M
desc:The monitor of class 1821801z
Process finished with exit code 0
*/
}
說(shuō)明:
在考試中,不推薦使用cin和cout進(jìn)行輸入輸出,因?yàn)樵跀?shù)據(jù)量較大的情況下,有可能數(shù)據(jù)還沒(méi)有輸入完就超時(shí)了,因此只有在十分必要的情況下再去用cin和cout函數(shù),推薦優(yōu)先使用C語(yǔ)言的scanf()和printf()函數(shù)。
浮點(diǎn)數(shù)的比較
由于計(jì)算機(jī)中采用有限位的二進(jìn)制編碼,因此浮點(diǎn)數(shù)在計(jì)算機(jī)中的存儲(chǔ)并不總是精確的,并且再經(jīng)過(guò)大量計(jì)算后,誤差會(huì)更加明顯,這樣就會(huì)對(duì)比較操作造成極大的干擾。
于是,為了提高浮點(diǎn)數(shù)比較結(jié)果的準(zhǔn)確性,我們需要引進(jìn)一個(gè)極小數(shù)eps來(lái)對(duì)誤差進(jìn)行修正。
這樣,當(dāng)一個(gè)數(shù)a落在[b-eps,b+eps]時(shí),我們就應(yīng)判斷a==b是成立的。
實(shí)際上,eps可以任取,但經(jīng)驗(yàn)表明,eps取108最合適。
const double eps = 1e-8;
我們把比較操作寫成宏定義的形式:
#define equ(a,b) ((fabs((a)-(b)))<(eps))
于是,我們可以這樣對(duì)兩個(gè)浮點(diǎn)數(shù)進(jìn)行比較(注意觀察兩種方式的結(jié)果):
#include <cmath>
#include <cstdio>
const double eps = 1e-8;
#define Equ(a,b) ((fabs((a)-(b)))<(eps))
int main(){
double d1 = 4 * asin(sqrt(2.0) / 2);
double d2 = 3 * asin(sqrt(3.0) / 2);
// 方式1
printf("%d\n",(d1==d2));
// 方式2
printf("%d\n",Equ(d1,d2));
return 0;
/*
* /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
0
1
Process finished with exit code 0
*/
}
我們可以寫出其他運(yùn)算符的宏定義形式:
// 大于(<)
#define More(a,b) ((a)-(b)) > (eps)
// 小于(<)
#define Less(a,b) ((a)-(b)) < (-eps)
// 不大于(<=)
#define LessEqu(a,b) ((a)-(b)) < (eps)
// 不小于(>=)
#define MoreEqu(a,b) ((a)-(b)) > (-eps)
關(guān)于圓周率π
圓周率π不需要死記,由 "cos(π) = -1" 得 "arccos(-1) = π",即<code>const double Pi = acos(-1.0);</code>
END