2012年11月17日星期六
曾军提供的代码,主要作用是将数字组成的字符串,分解成一个一维数组。
自己测试后,加以注释的代码:
|
# 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 |
而比较专业的解释:
|
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 <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++的运算符。它们都可用于申请动态内存和释放内存。 |
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编译的就是这个数 |
到底如何,以后可能会慢慢清楚的,现阶段学艺不精,看不透,所以这个问题到此为止。
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日星期二 数据结构学习——连续存储数组的算法演示 代码(最终版): |
C++字符串转数组及链表实现
本文详细介绍了如何将数字字符串转换为一维字符数组,并探讨了C/C++中动态内存分配的方法。此外,文章还展示了链表的基本实现过程,包括初始化、插入、删除等操作。
2497

被折叠的 条评论
为什么被折叠?



