编程语言 - webdancer's Blog
c++学习笔记5
突然发现有一个很重要的地方,但是一直不太明白。那就是引用与指针的区别,对指针思考的比较多,但是引用确实想当然。我的最大特点就是:想当然,缺少思考。什么是引用呢?
int a=0;
int & ra=a;
引用就是对象的另一个名字,不引入新对象。
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
引用的使用场合:
1.参数传递,某些大型对象可以节省空间。
2.重载操作符时,应该使用引用。例如:[]。
当然,使用引用的地方,可以使用指针。不知道,大家怎么理解的。
c++笔记4
c/c++的数组与指针问题还是没有搞得太清楚,再仔细的研究一下。
指针:指向对象,存放对象的地址。
数组:一块连续的内存空间,静态初始化时确定数组的大小。
动态内存分配:在程序空间的动态内存区(堆)进行的空间分配。
赋值表达式:
LEFT = RIGHT
在赋值表达式,左右都能出现的成为左值。如:LEFT;只能出现在右边的称为右值。
在C语言里,又将左值分为了可修改与不可修改的左值。例如:数组名,就是个不可修改的左值。
int a[4]={1,2,3,4}; int *pa=a;
这样,pa与a都可以来引用数组里面的元素了,但是a与pa还是有区别的:pa可以作为可修改的左值,用来指向其他的对象,但是a是一个不可修改的左值,不能指向其他的对象。
数组名和指针的区别就是:数组名作为一个符号,在编译时是可知的,可以直接取到a的值。而指针作为变量,必须首先取得指针的值,然后得到地址。
通常,定义指针:
int *p = 0; // 或int *p = NULL; int *p = new int;//C中用:int *p = (int *)malloc(sizeof(int));
二维数组的问题:
在c/c++里没有所谓的真正的二维数组,只有数组的数组,就是数组的元素还是数组,也是连续分配的空间。
例如:
int a[4][4]; int main(){ int i=0; cout<<a[i]<<endl; cout<<&(a[i])<<endl; cout<<a+i<<endl; cout<<*(a+i)<<endl; cout<<*(a[i])<<endl; char c; cin>>c; }
运行的结果为:
00A88138
00A88138
00A88138
00A88138
0
分别的意思是:
a[i]:第i行第0列地址。
&a[i]:第i行行首的地址。
a+i:第i行行首的地址。
*(a+i):第i行第0列地址。// *(a+i)+j与a+i+j 就有了明显的区别。
可以看出通过*(a+i)的行地址转为列地址,这样可以继续访问列里的元素。为什么:*(a[i])的值为:0,不明白??
怎么申请动态的二维数组:
c语言:
int **pp=0, i; pp = (int **)malloc(sizeof(int*)*row); for (i=0; i<row; i++) pp[i] = (int *)malloc(sizeof(int)*colum);
c++语言:
int **pp=new int* [row]; for(int i=0;i<row;++i){ pp[i]=new int[colum]; }
当然,指针的理解还得靠以后的逐渐积累,例如在函数参数的传值的应用,函数指针,太强大,真是有点晕。参考了很多人的东西,表示感谢。
c++学习笔记3
学习C++表达式时首先就是表达式,常见到的算术,关系,逻辑,赋值,条件,逗号等与C的一致,而且比较熟悉。主要是了解一下位操作,自增、自减,箭头,sizeof等。
1。位操作:~(求反),<<(左移),>>(右移),&(位与),^(为异或),|(位或)。可以对整型值进行运算,但是最好是对无符号整型的运算。其实,位运算的语法并不难,难得是二进制运算,必须按位运算,对各种类型必须十分熟悉。其实,用c++自带的bitset 类更简单,容易。
.2。自增(自减)运算:记住两点:
》后置操作符返回未加1时的值。
》前置操作符返回加1后的值,即对象本身。
vector<int> a(4,1); vector<int>::iterator iter=a.begin(); while(iter!=a.end()) cout<<*iter++<<endl
注意:*iter++:等价于:*(iter++),由于为后置++,所以解引用的是未加1之前的值。
.3。箭头(->):为指针类型的变量来取得属性。
4。sizeof : 返回一个类型或对象的长度,返回类型为:size_t。特别的:
》&类型是为返回对象的长度。
》*类型返回指针类型的长度。
》数组返回数组长度乘以数组类型的长度。
复合表达式的问题:
优先级,结合性真的不好记,真的需要的时候就查表吧!(ps:最近学编译,才知道什么叫烦。。必须仔细搞懂)。此外,注意求值顺序的问题。这是个很有趣的问题,
int a[2]={1,2}; int i=0; if(a[i++]<a[i]) cout<<"a[0]<a[1]"<<endl;
如果左边先计算,a[0]<a[1],则会输出;如果右边先计算,a[0]<a[0],则不会输出。在我的机子里,不会输出。
new和delete的问题:
int *i=new int(6); cout<<*i<<endl;//1 delete i; i=0; cout<<*i<<endl;//2
delete以后,例如delete i 后,i变成了悬浮指针,此时可使用此指针。最好立即将此指针赋值为0。然后,使用此指针会有异常出现。上面的例子中:第二次cout会出现异常。不同的编译器处理也不同,在vc中,上面的例子无法运行;在gcc中可以运行。在动态内存管理中,经常造成内存管理错误,比如删除指针错误,读取删除的对象。
类型转换:
隐式类型转换可能要理解一下,经常用,但是以前不太明白。
string s; while(cin>>s)
不知道测试的什么,在这里会做类型转换。
python学习
python是一种脚本语言,不用经过编译。这是我学习的第一种不用经过编译的高级语言。python有很多的分支,通常的python 解释器是用c 实现的。
启动python的方式,通常有三种,(1)命令行交互;(2)脚本;(3)GUI图形界面。我在linux下面学习,所以选择第一种。
命令选项:可以通过man python 來查询。下面是通常用到的:
-d: 提供调试输出。
-O:生成优化的字节码
-S :不导入site模块。
-v :冗余输出。
-m mod :将某一模块以脚本方式运行。
file :从脚本文件运行。
基本要素:
1) 输出: print ; 可以格式化输出。 2)输入 :内置函数:raw_input(“提示内容”);
2)运算符:算术运算:+,-,*,/,%,//,**;
关系运算:>,<=,<,>=,==,!=,<>;
逻辑运算:and , or ,not.
注:通常使用help()可以查询函数功能。
3)变量:动态语言,使用前不必声明。
4)字符串:[]:索引;+:连接;*:重复。
5)缩进:代码中用缩进来表示块,而不是大括号.
结构语句:条件,循环的结构。
条件:
if expression1:
if_suite
elif expression2:
elif_suite
else:
else_suite
循环:
while expression:
while_suite
for item in List
do_for
函数:
def Function_name([arguments]):
'may have some clairation'
functionblock
类定义:
class ClassName(base_class[es]):
"optional documentation string"
static_member_declarations
method_declarations
模块:
模块是一种组织形式, 它将彼此有关系的 Python 代码组织到一个个独立文件当中。
模块可以包含可执行代码, 函数和类或者这些东西的组合。
import 模块名
文件:
打开文件:FileHanle=open(File_path,acessMode);
et:
filename = raw_input('Enter file name: ')
fobj = open(filename, 'r')
for eachLine in fobj:
print eachLine,
fobj.close()
异常处理:
try:
code_block
except EXCEPTION, e:
exception_code
感觉:python与我以前学的语言真得不同,没了大括号,但要加:,还要注意缩进。但是,也很简单比较容易。
书上给的几个函数:
dir([obj])
显示对象的属性,如果没有提供参数, 则显示全局变量的名字
help([obj])
以一种整齐美观的形式 显示对象的文档字符串, 如果没有提供任何参数, 则会进入交互式帮助。
int(obj)
将一个对象转换为整数
len(obj)
返回对象的长度
open(fn, mode) 以 mode('r' = 读, 'w'= 写)方式打开一个文件名为 fn 的文件
range([[start,]stop[,step])
返回一个整数列表。起始值为 start, 结束值为 stop - 1; start
默认值为 0, step默认值为1。
raw_input(str) 等待用户输入一个字符串, 可以提供一个可选的参数 str 用作提示信息。
str(obj)
将一个对象转换为字符串
type(obj)
返回对象的类型(返回值本身是一个 type 对象!)
Pythonic八荣八耻
以打印日志为荣 , 以单步跟踪为耻;
以空格缩进为荣 , 以制表缩进为耻;
以单元测试为荣 , 以人工测试为耻;
以模块复用为荣 , 以复制粘贴为耻;
以多态应用为荣 , 以分支判断为耻;
以Pythonic为荣 , 以冗余拖沓为耻;
以总结分享为荣 , 以跪求其解为耻;
c++笔记2
现在才觉得当自学的时候,应该看一本好书。先到网上搜一下,再下决定。记得当时学C的时候,看的那本书并没有把C的特点给说明白,对指针也是很含糊。现在看着本书,真的很好。
1.数组初始化。
如果没有显式的初始化:
》在函数体外定义的内置数组,会进行初始化:0。
》在函数体内定义的内置数组,不进行初始化。
》类类型,不论定义在何处,都自动调用默认构造函数。若没有默认的构造函数,则必须显式的初始化。
2.数组不能直接赋值,而且一定要保证下标的范围。说起来简单,我就经常犯错误。
3.const与*。
我以为理解的可以了,一个例子又把我搞晕了。
string s1="hello";
string s2="world";
typedef string * pstr;
const pstr str=&s1;
*str="world";
cout<<*str<<endl;
正常编译,不会出错。原来理解成了:const string * str。关键把typedef的作用理解错了,认为成文本替换了。正确的是:
string * const str。
ps: The typedef keyword allows you to create a new alias for an existing data type.
4.减少c风格string的使用。主要是:减少错误。
c++学习笔记
其实,以前是自学过C++的,但是,感觉很挫。于是,又看《c++ primer》。觉得,这本书解释的很清楚,而且,很多提醒的地方,很好。就记录 一下。
(1)声明和定义。
变量的定义为变量分配存储的空间,还可以初始化。在一个程序中,变量只能定义一次。
变量的声明用于向程序说明变量的类型和名字。定义也是声明。可以 用extern来声明而不定义。
(2)const限定符。
容易混淆的原因是:c中的const与c++的const完全不同,在c中的const只是readonly的意思,并不是真正的常量定义符号,只是不能被赋值,但是,不能保证不被修改。而在C++中,const就是定义常量,而且是定义在该文件上的局部变量。
const 修饰指针符号*,位置不同时意义不同,这都是由于c语言声明的复杂性。 《c专家编程》有总结。
(3)头文件。
在头文件中,不应该含有变量或是函数的定义,但是可以定义类,const对象,inline函数。
(4)string.
标准库定义的string类型字符串,与字符串字面量不是同一类型。例如:两个字符串字面量不能用+来连接,但是string类型变量就可以。
c函数指针
//声明整数相加函数 int add_int(int a, int b) { return a + b; } //声明浮点数相加函数 float add_float(float a, float b) { return a+b; } //定义函数指针类型 typedef int (*int_add_funtion)(int a,int b); //定义函数指针类型 typedef float (*float_add_funtion)(float a , float b); int main() { //声明一个函数指针,名字叫做int_add_fun,相当于创建int_add_funtion这个类型的实例,下同 int_add_funtion int_add_fun; //声明一个函数指针,名字叫做float_add_fun float_add_funtion float_add_fun; //将该函数指针指向 整数相加函数 的入口地址 int_add_fun = add_int; //将该函数指针指向 浮点数相加函数 的入口地址 float_add_fun = add_float; //以常规方式调用 整数相加函数,打印出100+200的计算结果 printf("%d\n", add_int(100,200)); //用函数指针调用 整数相加函数,打印出100+200的计算结果 printf("%d\n", (*int_add_fun)(100,200)); //以常规方式调用 浮 点数相加函数,打印出100.32 + 324.54的计算结果 printf("%f\n", add_float(100.32f, 324.54f)); //用函数指针调用 浮点数相加函数,打印出 100.32 + 324.54的计算结果 printf("%f", (*float_add_fun)(100.32f, 324.54f)); return 0; }
重新拾起c——符号
以上为符号的列表。对符号我们就是知道他们经常用的意思!
注意:
1)/* :是注释号,编译器会自动寻找*/与之匹配。int i = 8; int * pi=&i; int j=i/*pi; j的定义有问题。应为:j=i/(*pi);
2)对一个新手来说,注释可能很重要!要写好。
3)\:持续符和转义符。
转义字符转义字符的意义
\n 回车换行
\t 横向跳到下一制表位置
\v 竖向跳格
\b 退格
\r 回车
\f 走纸换页
\\ 反斜扛符"\"
\' 单引号符
\a 鸣铃
\ddd 1~3 位八进制数所代表的字符
\xhh 1~2 位十六进制数所代表的字符
4)逻辑运算符:
&& ,|| :自动判断,如果前面可以判定真假,后面就不理会了。
5)位运算符:
& 按位与
| 按位或
^ 按位异或
~ 取反
<< 左移
>> 右移
位运算符对底层编程很重要。
6)++,--。
有些人不建议使用++,--。因为很多时候,非常容易造成错误!其实,就是优先级问题。对优先级加括号应该是一个好方法!
8)优先级:
尽管我们可以通过加括号來控制,但是阅读他人的代码,还是很有用!
Operator(s) | Description | Associativity | |
17
|
:: | global scope (unary) |
right-to-left
|
17
|
:: | class scope (binary) |
left-to-right
|
16
|
-> . | member selectors |
left-to-right
|
16
|
[ ] | array index |
left-to-right
|
16
|
( ) | function call |
left-to-right
|
16
|
( ) | type construction |
left-to-right
|
16
|
sizeof | size in bytes |
left-to-right
|
15
|
++ -- | increment, decrement |
right-to-left
|
15
|
~ | bitwise NOT |
right-to-left
|
15
|
! | logical NOT |
right-to-left
|
15
|
+ - | unary plus, minus |
right-to-left
|
15
|
* & | dereference, address-of |
right-to-left
|
15
|
( ) | cast |
right-to-left
|
15
|
new delete | free store management |
right-to-left
|
14
|
->* .* | member pointer selectors |
left-to-right
|
13
|
* / % | multiplicative operators |
left-to-right
|
12
|
+ - | arithmetic operators |
left-to-right
|
11
|
<< >> | bitwise shift |
left-to-right
|
10
|
< <= > >= | relational operators |
left-to-right
|
9
|
== != | equality, inequality |
left-to-right
|
8
|
& | bitwise AND |
left-to-right
|
7
|
^ | bitwise exclusive OR |
left-to-right
|
6
|
| | bitwise inclusive OR |
left-to-right
|
5
|
&& | logical AND |
left-to-right
|
4
|
|| | logical OR |
left-to-right
|
3
|
? : | arithmetic if |
left-to-right
|
2
|
= *= /* %= += -= |
assignment operators |
right-to-left
|
1
|
, | comma operator |
left-to-right
|
当然,得经常调试代码!