C和C++学习心得(更新中)
1.关于库函数的调用,使用strcmp(),strcpy(),strcat()等函数,需要加上#include
2.字符的输入可使用cin.get(),和C中gets()函数的用法差不多,如ar=cin.get(),可用于在多组字符串的输入中吸收无关字符(如输入数据后的回车击键)。而字符串的输入可以使用cin.getline()函数,该函数使用规则:cin.getline()实际上有三个参数,cin.getline(接受字符串到m,接受个数5,结束字符),当第三个参数省略时,系统默认为'\0' 是'/n'吧。相关详解
示例代码
int repeat,i;
char c,ar,str[100];
cin>>repeat;//输入循环次数
for(i=1;i<=repeat;i++){
ar=cin.get();//吸收回车的击键
cin.getline(t,100);
cin>>m;
strmcpy(s,t,m);//调用一个自定义函数
}
3.字符和字符串的输出,使用cout即可,输出字符串记得要用字符数组的首地址(即函数名)。值得一提的是在C语言中,%g的作用(详解)
还有就是强制转换(type)可以用于浮点数的取整数部分的运算,下面的代码可以将实数分为整数部分和非整数部分两部分。
#include <stdio.h>
void splitfloat( float x, int *intpart, float *fracpart );//用于将实数拆分成整数部分和小数部分
int main()
{
float x, fracpart;
int intpart;
scanf("%f", &x);
splitfloat(x, &intpart, &fracpart);
printf("The integer part is %d\n", intpart);
printf("The fractional part is %g\n", fracpart);
return 0;
}
void splitfloat( float x, int *intpart, float *fracpart )
{
int i,len=0;
float store;
*intpart=0;
if(0.0<=x&&x<1.0){
*fracpart=x;
}
else{
*intpart=(int)x;
*fracpart=x-*intpart;
}
}
4.在这里提一下,指针数组的使用。示例如下:
const char*week[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
其实在这里我有一些疑惑,把char*前的const去掉,编译器会报错????相关用法和说明
5.无形参和实参的自定义函数使用
如无返回值:
声明:void a(void);
定义:void a(void){}
调用:a(); 或 a(void);
有返回值就把void换成相应类型即可
6.关于string类型(相关详细内容)
(和数组很像)甚至可以如下这么操作:
string name="ycy"
name="This is"+name;//输出 This is ycy
还可以使用函数
#include <iostream>
#include <string>
using namespace std;
int main()
{
string strDemo = "I am";
strDemo.insert(4, " good.");
cout << "strDemo is: " << strDemo << endl;
return 0;
}
下面这段代码可以完成string类型的a与char类型的temp数组的连接,并把得到的新字符串储存在a中
字符串(字符数组和string都可)的连接可使用strcat函数:strcat(str1,str2),把str1的尾和str2的头连接,并把新字符串储存到str1中。
string类型的连接:str1=str1+str2(str1必须放前面)
#include<iostream>
#include<string>
using namespace std;
string a="Hello",b="1";
char temp[100]="World";
int main()
{
b.assign(temp, sizeof(temp));//利用此语句可将temp数组中储存的字符串赋给string类型的b(#include<string>)
cout<<b<<endl;
a=temp+a;
cout<<a;
return 0;
}
7.动态内存分配和释放
·void*malloc(unsigned size)和free()
具体使用
int *p;
p=(int*)malloc(sizeof(int));//申请一个int类型的内存空间
free(p)//用完后记得释放
p=(int*)malloc(n*sizeof(int));//申请n个int类型数据的内存空间,此时p相当于一个长度为n的数组的首地址
free(p)//用完后记得释放
·也可使用new和delete关键字 new和delete的用法
int*p;
p=new int;//直接申请一个int 类型的数据内存空间
delete p;//释放内存空间
p=new int[num]//申请n个int类型数据的内存空间,此时p相当于一个长度为n的数组的首地址(num为一个已知数?)
delete p;
使用new关键字动态申请一个三维数组
float (* fp)[25][10];
fp=new float[10][25][10];
8.链表的使用注意事项
若单链表非空,头指针head一定指向单链表中的第一个节点。如果有头结点,则head指向头结点。
有头结点的单链表永远非空(头结点:head=头结点的地址,head->next=第一个有存实质性内容的节点,头结点本身的数据域不存啥有用的东西),有头结点的话,在删除,插入等操作中,就不需要判断所在的节点位置情况,可使用统一的处理方法,比较方便。
没有头结点的单链表,单链表为空时,head=NULL。
在操作单链表时,要特别注意不要使用越界,特别注意在遍历链表或搜寻特定节点时,p,p->next是否都不能为NULL。
在对链表中的结点进行排序时,记得只需置换数值域的数据。
对链表的几种基本操作
#include <iostream>
#include<malloc.h>
using namespace std;
struct Node {
int data;
Node* next;
};
void IniNode(Node** head)//准初始化函数
{
(*head) = (Node*)malloc(sizeof(Node));
if ((*head) == NULL)
{
cout << "Fail!" << endl;
exit(0);
}
else cout << "Succeed!" << endl;
(*head)->next = NULL;//该链表有头结点
}
Node* GetNode(int item)//创建动态节点(存有数据)
{
Node* newp = (Node*)malloc(sizeof(Node));
if (!newp)
{
cout << "Overflow" << endl;
exit(0);
}
newp->data = item;
newp->next = NULL;
return newp;
}
void InsetAfter(Node* p, Node* newp)//后插运算
{
newp->next =p->next;
p->next = newp;
}
void ListInsert(Node* head, int item)//将新增链表结点按升序插入
{
Node *p = head,*newp;
newp = GetNode(item);
while (p->next)
{
if (p->next->data < item)
p = p->next;
else break;
}
InsetAfter(p, newp);
}
Node* DeleteAfter(Node* p)//后删操作,删除p后的结点
{
Node* temp = p->next;
if (temp)
p->next = temp->next;
return temp;
}
Node* FindNode(const Node* h, int item)//查找指定结点
{
Node* p = h->next;
while (p)
{
if (p->data == item)
break;
p = p->next;
}
return p;
}
void ListClear(Node* h)//清表操作,清到只剩一个头结点的空单链表
{
Node* p = DeleteAfter(h);
while (p)
{
free(p);
p = DeleteAfter(h);//此处注意,删的结点一直是head头结点后的结点
}
cout << "Clear!" << endl;
}
void Revert(Node* h)//逆置链表操作
{
Node* rear = h->next,*p;
while (rear->next)
{
p = DeleteAfter(rear);
InsetAfter(h, p);
}
}
void disp(Node* head)//展示链表
{
for (Node* ptr = head; ptr->next; ptr = ptr->next)
{
cout << ptr->next->data << endl;
}
}
int main()
{
Node *head = NULL,*p=NULL;
int num[5] = { 1,3,5,4,2};
IniNode(&head);
for (int i = 0; i < 5; i++)
{
ListInsert(head, num[i]);
}
disp(head);
cout << endl;
Revert(head);
disp(head);
ListClear(head);
return 0;
}
9.初始化数组
方法一:在定义int类型数组时,如果写成:
int a[1000]={1};
此时,数组中除了a[0]=1,其他元素全部被系统初始化为0
方法二:memset()函数,可用于多次初始化 memset函数(初始化) c++语言中memset函数怎么用?
#include<stdio.h>
#include<string.h>
int main
{
int a[100];
memset(a,0,sizeof(a));
return 0;
}
9.关于常量的使用
·宏定义
用 #define 定义标识符的一般形式为:
#define 标识符 常量 //注意, 最后没有分号,标识符常用大写字母组成
·使用const关键字
整型常量定义:如:
const int MAX=1;
实型常量定义:如
//C编译系统对实型常量不分float和double,都作double处理以更精确,也可以在实型常量后面加上字母f或F来指定其为单精度实型(float)
//3.1415(double型实型常量)3.1415f(float型实型常量) .87L(long double型实型常量)
const double FIRST=3.1415926;
const double SECOND=3.1415926f;
10.关于inline关键字的使用 inline关键字的用法详解
·声明内联函数时使用关键字inline
格式为:
inline 返回值类型 函数名(形参表)
{
函数体
}
声明和函数体需要出现在调用之前,不允许先给出函数原型,在调用之后才给出函数体