11月学习笔记总结
来源:互联网 发布:电脑远程软件安卓版 编辑:程序博客网 时间:2024/04/28 08:34
2012年11月17日星期六
曾军提供的代码,主要作用是将数字组成的字符串,分解成一个一维数组。
#include "iostream"
using namespace std;
#include "string"
int main()
{
string str = "12345353";
char *p_ch = new char[str.length() + 1];
for(int i = 0; i < str.length(); i++)
{
p_ch[i] = str.at(i);
}
p_ch[i] = '\0';
for(int j = 0; j < strlen(p_ch); j++)
{
cout<<p_ch[j]<<endl;
}
return 0;
}
自己测试后,加以注释的代码:
# include <iostream>
# include <string>
using namespace std;
int main()
{
//声明并定义字符串
string str = "0102335487";
//为字符串申请一个长度为str.length()的动态内存
char *p_ch = new char[str.length()+1]; //这里的str.length()+1一定要+1
//用方法at将字符串中的元素循环赋值
for(int i=0;i<str.length();i++)
{
p_ch[i] = str.at(i);
}
p_ch[i]='\0'; //这里有零系统才能结束,没有这句话,系统会不停的输出内存中的垃圾数据,知道碰巧遇到一个零,才会终止。
//将赋值的变量循环输出
for(int j=0;j<strlen(p_ch);j++)
{
cout<<p_ch[j]<<endl;
}
return 0;
}
问题:1. j<strlen(p_ch),什么意思
2. p_ch[i]='\0'; 语句中的i,应该是属于上一个for循环中的,i的生命周期应该已经结束,作用域也不在花括号外了,为什么还能调用。
关于VC++6.0的编译build和compile的区别(F7与CTRL+F7)
一般人的解释如下:
buid比compile强大一点。运行的时候就知道,时间是不一样的。有人用过下面的方程式:
BUILD = COMPILE + LINK = RESULT IS EXE
COMPILE = COMPILE = RESULT IS DCU
而比较专业的解释:
Build是从新编译所有和生成exe有关的文件,无论.pas文件是否修改过,它都会重新生成新的.dcu,并从新链接这些.dcu等等文件。
Compile是编译修改过的文件,它只生成新修改过的.pas的相应的.dcu,并从新链接这些改变过的.dcu等等文件。
(反正这两个解释我没看懂,但至少知道build比compile做的工作多一些,而且一般我们编程序编译的时候用CTRL+F7,即compile就够了)
2012年11月18日星期日
在《操作系统》的课程中的C语言编程实验碰到的几个函数:
函数名:sleep
功能:执行挂起一段时间
注:
1. VC中的sleep函数‘s’要大写,即Sleep;而其他的都是小写。
2. Sleep()里面,以毫秒为单位;Linux里sleep()以秒为单位。
2012年11月19日
针对“Z码解读与加密”工作的代码增进:
# include <iostream>
# include <string>
using namespace std;
int main()
{
string str = "123455157487814684";
char *p_ch = new char[str.length()+1];
for(int i=0;i<str.length();i++)
{
p_ch[i]=str.at(i);
}
p_ch[i]='\0';
for(int j=0;j<strlen(p_ch);j+=2)
{
cout<<p_ch[j]<<p_ch[j+1]<<endl;
}
return 0;
}
其中最后一个for循环的j+=2也就是j=j+2,实现了隔一个数字输出的效果,并且修改cout<<p_ch[j]<<p_ch[j+1]<<endl;
所以运行后的结果为:
2012年11月20日星期二
1. C和C++中动态申请内存:
在C++中,似乎所使用的语句要简单一些,包含的头文件是#include<iostream.h> 申请内存不需要调用函数只要一个关键字new即可。
注意昨天“Z码”代码中的语句:
char *p_ch = new char[str.length()+1];
这个语的意思就是为p_ch申请str.length()+1个char型变量的内存空间,注意是方括号,如果是圆括号的话,例如:
int *Array;
Array = new int(10);
就不是申请10个int型变量的内存空间了,而是申请一个int型的内存空间,然后给它赋值为10。
new 是C++的关键字,不是C的,而C++可以使用malloc。
以下是C语言中的动态内存申请的说明:
在C语言中要使用动态内存要包含一个头文件即 #include<malloc.h> 或者是#include<stdlib.h>,然后用C语言的系统函数 void * malloc (usigned size);来获得动态分配的内存,这个函数参数是需要申请的内存的字节数,返回的是一个申请到的内存的首地址,这个返回的内存的类型是 void ,所以需要根据需要进行强制类型转换,例如 int *array; array= (int *)malloc(sizeof(int)*10);这样就动态申请到了一个有10个int型变量的内存空间了。
相应的补充:现在不是很理解,以后慢慢理解
malloc和free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求,对象在创建对象的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数与析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。
2. 函数strlen
“Z”代码中的语句:
for(int j=0;j<strlen(p_ch);j+=2)
其中,strlen()函数包含的头文件是<string>,strlen所作的仅仅是一个计数器的工作,它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止,然后返回计数器值。
百度百科对此函数的介绍:
原型:extern unsigned int strlen(char *s);,在Visual C++ 6.0中,原型为size_t strlen(const char *string);,其中size_t实际上是unsigned int,在VC6.0中可以看到这样的代码:typedef unsigned int size_t;。
头文件:string.h
格式:strlen (字符数组名)
功能:计算字符串s的(unsigned int型)长度,不包括'\0'在内
说明:返回s的长度,不包括结束符NULL。
3. 同上,语句:
char *p_ch = new char[str.length()+1];
其中的str.length()代表的是
String.Length
Length 属性返回此实例中 Char 对象的个数,而不是 Unicode 字符个数。原因在于一个 Unicode 字符可能会用多个 Char 表示。使用 System.Globalization.StringInfo 类来处理每个 Unicode 字符而不是每个 Char。
“Z码”代码增进:
# include <iostream>
# include <string>
using namespace std;
int main()
{
string a;
cout<<"请输入密码:";
cin>>a;
//string str = "123455157487814684";
char *p_ch = new char[a.length()+1];
for(int i=0;i<a.length();i++)
{
p_ch[i]=a.at(i);
}
p_ch[i]='\0';
for(int j=0;j<strlen(p_ch);j+=2)
{
cout<<p_ch[j]<<p_ch[j+1]<<endl;
}
return 0;
}
2012年11月21日星期三
1. 将输入字母大小写转换:
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
char letter = 0;
cout << endl
<< "Enter a letter:";
cin >> letter;
cout << endl;
if (isupper(letter)) //判断字母为大写为真,则运行以下代码
{
cout << "You entered a capital letter."
<<endl;
cout << " Converting to lowercase we get "
<< static_cast<char>(tolower(letter)) //由于tolowe()函数返回的值是int类型,因此把它强制转换为char类型。
<<endl;
return 0;
}
if (islower(letter)) //判断字母为小写为真,则运行以下代码
{
cout << "You entered a small letter."
<< endl;
cout << "Converting to uppercase we get "
<< static_cast<char>(toupper(letter)) //同上强制转换
<< endl;
return 0;
}
cout << " You id not enter a letter."
<< endl;
return 0;
}
其中,用到了头文件<cctype>中转换字符的函数:tolower()和toupper()。并且这两个函数的返回值是int类型的,所以在一些语句中用了强制转换static_cast<char>(),将int类型强制转换为char类型,并输出(注释中有)。
注意:以上代码描述的是,单字符的大小写转换,那么多字符的只能识别一个字母,比如我输入ea那么程序只能识别e不能识别到a,所以程序只能将e转换为大写。
所以如果需要使用多字节字符(其类型是wchar_t),就可以包含头文件<cwctype>。该头文件的名称和<cctype>只差一个w。该文件包含了在<cctype>中声明的所有函数的对应多字节字符。每个测试函数名都在is的后面加上了w,所以它们的名称就变成:
iswupper(),iswdigit(),iswspace()等等
它们都传递多字节字符参数,并且返回一个int值,就像处理char类型的字符函数一样。同样,多字节符转换函数也成为towupper()和towlower()。(to后面加了w),但是对于以上代码修改使得成为转换多字符大小写暂时不能达成。
2012年11月24日星期六
关于《郝斌数据结构》的链表实现:
1. 为什么是 -858993460?
通过代码的还原,无论是视频教学的代码还是自己的代码如下:
# include <stdio.h>
//(是一个结构体)定义了一个数据类型,该数据类型的名字叫做struct Arr,该数据类型含有三个成员,分别是pBase,len,cnt;(只是定义数据类型,并没有定义变量)
struct Arr
{
int * pBase; //存储的是数组第一个元素的地址
int len; //数组所能容纳的最大数组的个数
int cnt; //当前数组有效元素数组的个数
//int increment; //自动增长因子
};
void init_arr(struct Arr array); //初始化
bool append_arr(); //追加,添加元素到末尾
bool insert_arr(); //插入
bool delete_arr(); //删除
int get(); //可以获取到下标为什么的某个值
bool is_empty(); //判断是否空
bool is_fullI(); //判断是否满
void sort_arr(); //排序
void show_arr(); //显示
void inversion_arr(); //倒置
int main(void)
{
struct Arr arr; //这一步并没有创建出来arr这个变量,这个变量包括三个成员pBase、len、cnt,它们在内存中现在还都是垃圾数字,所以就需要下一步的初始化来创建这个数组。(如同刚建好的电影院里面没有观众一样的道理)
init_arr(arr);
printf("%d\n",arr.len);
return 0;
}
void init_arr(struct Arr array) //结构体变量不能加减乘除但是可以相互赋值
{
array.len = 98;
}
此时得到的结果都是-85899360,为什么会这样?
所以网上查了一下,原来不光是我有这个疑问。
类似如此的代码:
# include <stdio.h>
int main(void)
{
int a;
printf("%d",a);
}
得出的结果依然是-858993460
借用别人的经验:
1.当一个未初始化赋值的时候,他在内存就默认保存为-858993460;
2.如果变量的数据类型由于你的运算的溢出了,在内存中系统就自动改为-858993460。
注:一般的书上都会说如果一个变量未付值,系统会给他一个随机值。但实际测试VC++6.0 里实际上是-858993460。TC上的数值是随机,每次都不一样。
其他网络分析的观点则是:
1. vc 下未初始化的内存都是ccccccccccccccccccc
2. 设计成0xcccccccc是有特殊用意的……这个好像叫做Poison,未初始化的Pointer去取值的话会出错。肯定有人问为什么不弄成0x00000000,因为空指针是指针的有效状态,可能会误导人,而0xCCCCCCCC在Windows下永远不可能是一个指针的有效状态(不是NULL,不指向一个对象,不指向一堆对象紧接之后的区域),这就是在模拟野指针……
3. 用VC DEBUG编译的就是这个数
-858993460对应HEX为0xCCCCCCCC
0xCC在X86指令集中为int 3
DEBUG这个机制是为了程序出现内存越界时调试器可以捕捉断点这个异常
而在RELEASE下默认直接是内存清零,也就是用VC RELEASE编译以后显示的结果为0
到底如何,以后可能会慢慢清楚的,现阶段学艺不精,看不透,所以这个问题到此为止。
2. 数据结构学习——链表,及其内部方法的完善
阶段性代码:
# include <stdio.h>
# include <malloc.h> //包含了malloc函数
# include <stdlib.h> //包含了exit函数
//(是一个结构体)定义了一个数据类型,该数据类型的名字叫做struct Arr,该数据类型含有三个成员,分别是pBase,len,cnt;(只是定义数据类型,并没有定义变量)
struct Arr
{
int * pBase; //存储的是数组第一个元素的地址
int len; //数组所能容纳的最大数组的个数
int cnt; //当前数组有效元素数组的个数
//int increment; //自动增长因子
};
void init_arr(struct Arr * pArr, int length); //初始化 //分号不能省掉
bool append_arr(); //追加,添加元素到末尾
bool insert_arr(); //插入
bool delete_arr(); //删除
int get(); //可以获取到下标为什么的某个值
bool is_empty(struct Arr * pArr); //判断是否空
bool is_fullI(); //判断是否满
void sort_arr(); //排序
void show_arr(struct Arr * pArr); //显示
void inversion_arr(); //倒置
int main(void)
{
struct Arr arr; //这一步并没有创建出来arr这个变量,这个变量包括三个成员pBase、len、cnt,它们在内存中现在还都是垃圾数字,所以就需要下一步的初始化来创建这个数组。(如同刚建好的电影院里面没有观众一样的道理)
init_arr(&arr, 6); //不加&,要传递12个字节(三个4字节成员),而加上&,只传递一个地址,地址占4个字节,同时下面的init_arr()函数的参数要改成指针:*pArr
show_arr(&arr); //写&arr比较好,因为如果写arr的话,也需要传三个成员,12个字节,很麻烦,而地址不存这个问题。
//printf("%d\n",arr.len);
return 0;
}
void init_arr(struct Arr *pArr, int length) //结构体变量不能加减乘除但是尅相互赋值
{
pArr->pBase = (int *)malloc(sizeof(int) * length);
if (NULL == pArr->pBase) //分配失败就会把NULL赋给pBase,同样,分配成功就会把地址分配给pBase。
//所以必须检测,值是否是NULL,如果没有检测,如果没分配成功,就全错了。
{
printf("动态内存分配失败!\n");
exit(-1); //终止整个程序
}
else
{
pArr->len = length;
pArr->cnt = 0;
}
return; //写个return给别人看到,这个函数写到这里就终止了,不写的话,会给别人造成小小的困扰,别人不清楚到底写完了没有。
}
bool is_empty(struct Arr * pArr)
{
if (0 == pArr->cnt)
return true;
else
return false;
}
void show_arr(struct Arr * pArr)
{
/*if (数组为空)——如果很多歌数组的话,就需要用到函数来实现,即bool is_empty(struct * pArr);
提示用户数组为空
else
输出数组有效内容)——伪算法*/
if ( is_empty(pArr)) //这里的pArr不能写成&pArr,因为pArr已经是地址了,如果写了&,就代表了取了pArr的地址的地址,所以不需要加&pArr
{
printf("数组为空!\n");
}
else
{
for (int i=0; i<pArr->cnt; ++i)
printf("%d", pArr->pBase[i]); //指向pBase这个成员
printf("\n");
}
}
2012年11月27日星期二
数据结构学习——连续存储数组的算法演示
代码(最终版):
# include <stdio.h># include <malloc.h>//包含了malloc函数# include <stdlib.h>//包含了exit函数//(是一个结构体)定义了一个数据类型,该数据类型的名字叫做struct Arr,该数据类型含有三个成员,分别是pBase,len,cnt;(只是定义数据类型,并没有定义变量)struct Arr{int * pBase;//存储的是数组第一个元素的地址int len;//数组所能容纳的最大数组的个数int cnt;//当前数组有效元素数组的个数//int increment;//自动增长因子};void init_arr(struct Arr * pArr, int length);//初始化//分号不能省掉bool append_arr(struct Arr * pArr, int val);//追加,添加元素到末尾bool insert_arr(struct Arr * pArr, int pos, int val);//插入pos的值从1开始bool delete_arr(struct Arr * pArr, int pos, int * pVal);//删除,并且返回被删除数据,如果改变函数返回类型int delete_arr()那么删除成功与失败就无法判断,因为任何一个值都有可能是真,所以在不改变函数返回值类型的情况下,添加一个指针,int * pVal来接收int get();//可以获取到下标为什么的某个值bool is_empty(struct Arr * pArr);//判断是否空bool is_fullI(struct Arr * pArr);//判断是否满void sort_arr(struct Arr * pArr);//排序void show_arr(struct Arr * pArr);//显示void inversion_arr(struct Arr * pArr);//倒置int main(void){struct Arr arr;//这一步并没有创建出来arr这个变量,这个变量包括三个成员pBase、len、cnt,它们在内存中现在还都是垃圾数字,所以就需要下一步的初始化来创建这个数组。(如同刚建好的电影院里面没有观众一样的道理)int val;init_arr(&arr, 6);//不加&,要传递12个字节(三个4字节成员),而加上&,只传递一个地址,地址占4个字节,同时下面的init_arr()函数的参数要改成指针:*pArrshow_arr(&arr);//写&arr比较好,因为如果写arr的话,也需要传三个成员,12个字节,很麻烦,而地址不存这个问题。append_arr(&arr, 59);append_arr(&arr, 66);append_arr(&arr, -99);append_arr(&arr, -45);show_arr(&arr);/*if (delete_arr(&arr, 4, &val))//将val的地址,发给了函数中的 pVal,这样就可以通过函数内部pVal修改val的值,从而修改主函数的值{printf("删除成功!\n");printf("您删除的元素是:%d\n", val);//注意val需要在前面声明}else{printf("删除失败!\n");}append_arr(&arr, 2);append_arr(&arr, 3);append_arr(&arr, 4);append_arr(&arr, 5);insert_arr(&arr, 7, 99);append_arr(&arr, 6);append_arr(&arr, 7);append_arr(&arr, 8);if (append_arr(&arr, 8)){printf("追加成功!\n");}else{printf("追加失败!\n");}*/show_arr(&arr);inversion_arr(&arr);printf("倒置之后的内容是:\n");show_arr(&arr);sort_arr(&arr);printf("排序之后的内容是:\n");show_arr(&arr);//printf("%d\n",arr.len);return 0;}void init_arr(struct Arr *pArr, int length)//结构体变量不能加减乘除但是尅相互赋值{pArr->pBase = (int *)malloc(sizeof(int) * length);if (NULL == pArr->pBase)//分配失败就会把NULL赋给pBase,同样,分配成功就会把地址分配给pBase。//所以必须检测,值是否是NULL,如果没有检测,如果没分配成功,就全错了。{printf("动态内存分配失败!\n");exit(-1);//终止整个程序}else{pArr->len = length;pArr->cnt = 0;}return;//写个return给别人看到,这个函数写到这里就终止了,不写的话,会给别人造成小小的困扰,别人不清楚到底写完了没有。}bool is_empty(struct Arr * pArr){if (0 == pArr->cnt)return true;elsereturn false;}bool is_full(struct Arr * pArr){if (pArr->cnt == pArr->len)return true;elsereturn false;}void show_arr(struct Arr * pArr){/*if (数组为空)--如果很多歌数组的话,就需要用到函数来实现,即bool is_empty(struct * pArr);提示用户数组为空else输出数组有效内容)--伪算法*/if ( is_empty(pArr)) //这里的pArr不能写成&pArr,因为pArr已经是地址了,如果写了&,就代表了取了pArr的地址的地址,所以不需要加&pArr{printf("数组为空!\n");}else{for (int i=0; i<pArr->cnt; ++i)printf("%d ", pArr->pBase[i]);//指向pBase这个成员printf("\n");}}bool append_arr(struct Arr * pArr, int val){//满时返回falseif(is_full(pArr))return false;//不满时追加pArr->pBase[pArr->cnt] = val;(pArr->cnt)++;return true;}bool insert_arr(struct Arr * pArr, int pos, int val){int i;if(is_full(pArr))return false;if (pos<1 || pos>pArr->cnt+1)return false;for (i=pArr->cnt-1; i>=pos-1; --i){pArr->pBase[i+1] = pArr->pBase[i];}pArr->pBase[pos-1] = val;//该程序有漏洞,万一pos的值是负数怎么办,所以需要判断,前面加if语句(pArr->cnt)++;return true;}bool delete_arr(struct Arr * pArr, int pos, int * pVal){int i;if (is_empty(pArr))return false;if(pos<1 || pos>pArr->cnt)return false;*pVal = pArr->pBase[pos-1];//放在删除操作前面,将等待删除的元素赋给了形参pVal指向的主函数的val,因为函数的返回值中需要删除的元素,在以下的删除操作之后加的话,该元素就没有了。for (i=pos; i<pArr->cnt; ++i){pArr->pBase[i-1] = pArr->pBase[i];}pArr->cnt--;//删除完了,个数减一(同以上增加)return true;}void inversion_arr(struct Arr * pArr){int i = 0;int j = pArr->cnt-1;int t;while (i<j)//典型的a,b两个值互换,步骤:t=a;a=b;b=t;三步搞定。{t = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = t;++i;--j;}return;}void sort_arr(struct Arr * pArr){int i,j;int t;for (i=0; i<pArr->cnt; ++i)//用冒泡排序{for(j=i+1; j<pArr->cnt; ++j){if (pArr->pBase[i] > pArr->pBase[j]){t = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = t;}}}}
- 11月学习笔记总结
- 11月学习总结
- 11月学习总结
- 11月学习总结
- 11月学习总结
- 11月学习总结
- 今天的学习笔记以及月总结
- 11月英语学习总结
- 11月英语学习总结
- c++11月学习笔记
- 11月java学习笔记
- 月总结--笔记
- 《古月ROS探索总结》学习笔记1
- 《古月ROS探索总结》学习笔记2
- 11月-月总结
- 9月11日学习总结
- 英语学习月总结
- php学习月总结
- “Java之父”高斯林现在在做什么?
- 从谷歌宕机事件认识互联网工作原理
- Google Spanner:地球上最大的单一数据库
- 如何使地形图变得更为有趣
- Launcher研究
- 11月学习笔记总结
- POJ 1860 Currency Exchange
- 华为中兴表清白!愿向印度政府公布所有源代码
- A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux(or, "Size Is Everything")
- Fetch next
- CSS的哪个属性可以设置DIV模块居中显示?
- Windows 8“死期”已定:2018年1月
- dedecms会员个人空间相册展示
- 微博的架构