迫于刷题,简单刷了一遍C++入门教程,对一些基础知识作简单记录。
#include <iostream>
using namespace std;
int main(void)
{
int a;
cin >> a;
if (a > 0){
for(int i = a; i > 0; i--)
cout << "hello" << endl;
}
else if (a < 0)
cout << a << " less than 0" << endl;
else{
cout << a << " is 0";
cout << endl;
}
return 0;
}
int nums1[2][5] = {{1, 2, 3}, {4, 5, 6, 7}}; // Fill empty with 0.
int nums2[][3] = {{1, 2, 3}, {4, 5, 6}};
float nums3[] = {1.23, 2.34, 3.45};
``
在C++中,使用如下语句会报错:
```C++
int n1 = text1.size();
int n2 = text2.size();
int dp[n1][n2] = {{0}, {0}}; // all to zero
原因是C允许使用变量来定义数组长度,却不允许同时进行初始化赋值,需要在之后赋值。
C++利用指针进行动态数组的定义,需注意动态数组需及时释放以防止内存泄漏。下例是用指针和vector进行一维/二维数组创建的过程。
// dynamic 1-d array + initialization
int *a = new int[10]();
cout << a[2] << endl;
delete [] a;
// create a dynamic 2-d array whose size is 3*2
// (method 1) - preferred
int (*value)[2] = new int[3][2];
cout << value[1][1] << endl;
delete [] value;
// (method 2) - preferred
vector<vector<int>> value1(3);
for(int i = 0; i < value1.size(); i++)
value1[i].resize(2);
// (method 3) - not preferred
int **value2 = new int*[3];
for(int i = 0; i < 3; i++)
value2[i] = new int[2];
for(int i = 0; i < 3; i++)
delete []value2[i];
在C语言中我们如下在非初始化时对字符串变量赋值,但不可以进行字符串变量的互相赋值:
#include <string.h>
char str1[3][15];
//str1[0] = "abcde"; //False
strcpy(str1[0], "abcde");
在C++中,对字符串的处理变得更加自由:
char str1[] = "abc";
char str2[20];
cin.getline(str2, 10, '\n'); // string, max length, end char.
// char str3 = str1; // False
string str3 = str1;
char ch[] = ",";
string str1;
cin >> str1; //abc
string str2("def");
string str3 = "ghi";
string full_str = str1 + str2 + str3;
cout << full_str << endl;//abcdefghi
对于C++字符串更多的声明方式和操作函数详见博客。
通过&来得到变量的地址,例如&a
即为a的地址。通过*来读取声明过变量地址的变量的值,例如*(&a)
即为a的值。我们常常使用的指针变量,其变量值只是一个地址。
如下为指针使用简例:
int Value = 10;
// First implementation
// pointer variable'piVal' contains the address of 'Value'.
// piVal = &Value, *piVal = Value
int *piVal = &Value;
// pointer variable'piVal2' contains the address of 'piVal'.
// piVal2 = &piVal, *piVal2 = piVal
int **piVal2 = &piVal;
*piVal = 20;
// Second implementation
double Value = 1.23;
double* piVal = 0; // 0 means NULL but not zero, both 'int* a' and 'int *a' are legal.
piVal = &Value;
如下显示两种错误的声明方式,会造成指针变量指向不合法地址:
// WRONG CASE ! Pointer should point to a variable, but not a value.
int* piVal = 10;
int* piVal;
*piVal = 10;
int a[3][4];
int *p = a[0]; //method 1
int *p = &a[0][0]; // method 2
定义二维数组a[3][4],a代表&a[0]
,*(a+1)
即a[1]=&a[1][0]
,不难得到&a[i][j] = *(a+i)+j
,a[i][j] = *(*(a+i)+j)
。
在实际应用中可以使用指针数组,指针数组中的每个元素都是一个指针变量,指针变量的值指向其他变量的地址。如下例:
char *name[3] = {"dahan", "minguo", "wansui}; // name[1] = &("minguo")
char *p = "MinGuGu";// p = &(char), *p = "M", *(p+1) = "i"
cout << p << endl; // MinGuGu
cout << (int*)p << endl; // memory address
注意指针变量(如上例p)的值是可以改变的,eg将其地址加1从而指向&a[1]等。但以char a[10] = "GuGu"
方式定义时,a为指针常数,不可改变其值。
3. 指针与函数的关系
C++中可以将函数指针作为另一个函数的参数,以高效地改变调用的函数。与一般的函数指针常声明为全局/局部变量不同,参数型函数指针直接声明于函数的参数行中,如下例所示:
int add(int a, int b) {return a+b;}
int sub(int a, int b) {return a-b;}
int Math(int a, int b, int (*pfunc)(int, int)) {return pfunc(a, b);}
result = Math(a, b, add)//pfunc = add = &(fun(add))
将上例再演变一下,可以成为函数指针数组。如下例所示:
int (*pfunc[])(int, int) = {add, sub};
int a =1, b = 2;
cout << pfunc[0](a, b) << endl; //pfunc[0] = add = &(fun(add))
回顾C++的函数写法,可以参照这个例子:
void my_sum(int a, int b=20); // declaration 1
//void my_sum(int*, int*); // declaration 2
int main(){
int a, b;
cin >> a >> b;
my_sum(a, b);
return 0;
}
void my_sum(int a, int b){
cout << a+b << endl;
}
同样地,数组也可以作为函数的参数,例如下声明void fun1(int a[][2], float b)
。
同样地,指针也可以作为函数的参数和返回值,例如一个实现将两个字符串相加的函数,其声明可以这样写char* Stract(char*, char*)
,Stract函数的参数和返回值均为字符串。
void (*ptr)(void); //ptr为函数指针,函数无返回值,函数无参数
int (*ptr)(int); //ptr为函数指针,函数返回整数值,函数接受整数参数
//int *ptr(int); //ptr为函数名,函数返回整数指针,函数接受整数参数
char* (*ptr)(char); //ptr为函数指针,函数返回字符指针,函数接受字符串参数
在此基础上的函数指针初始化及赋值方法如下所示:
int fun1();
//declaration 1
int (*pfun)() = fun1;
//declaration 2
int (*pfun)();
pfun = fun1;
int main(int argc, char *argv[])
。(argc和argv只是默认命名,实际可变但大可不必)helloworld "look at GUGU" look.lovely.GUGU this is a test.
,argc的实际值为7,argv的长度为7,同时argv[0] = "helloworld",argv[6] = "test."。// a.cpp
#include<iostream>
using namespace std;
#include "b.cpp"
int x;
int main()
{
fun1();
cout << x << endl; // 886
return 0;
}
//b.cpp
#include <iostream>
extern int x;
void fun1(){
x = 886;
}
char* get_data(char*);
int get_data(int);
float get_data(float);
double get_data(double);
#define PI 3.14
,#define STR "GUGU"
,#define HELLOWORLD cout<<"helloworld"<<endl;
和#define FUN func1()
的形式进行常量、字符串、程序语句、函数名的宏定义(宏定义的本质是在编译时直接替换),以#undef PI
形式取消宏定义。#define CAL_S(l, h) ((l)*(h))/2.0
方式定义三角形面积计算函数。#include <filename>
加载默认系统目录下的文件。#include "filename"
优先加载当前程序工作目录下文件(也可以使用此语句加载系统目录的文件)。__LINE__
,__FILE__
,__DATE__
,__TIME__
和__STDC__
等宏辅助程序编写。#if
,#else
,#elif
,#endif
,#ifdef
和#ifndef
等。C++中包括结构(struct)、枚举(enum)、联合(union)与类型定义()typedef这四种自定义数据类型。
struct Student
{
char name[20];
int score;
int *p;
};
Student Barry = {"Barry", 100};
cout << Barry.name << endl;
🎅