1。变量在内存中存储时,会优先分配地址大的字节来存储变量的内容,存放数据也是由大到小。但是变量的起始地址是它的最小地址 (最后一位的地址).
2。scanf函数与gets函数比较
在接收字符串的时候,他们都会在结尾自动添加/0,所不同的是,scanf认为空格是/0,而gets认为回车时/0.这就意味着你无法用scanf接受一个英文句子作为数组内容,因为它一旦发现了空格就会认为这个句子已经结束了
3.函数
如果没有写返回值类型,默认是int
如果写了返回值,可以不返回
可以重复声明,不可重复定义
4.数组定义的错误写法
错误写法
a. int a[5];
a = {1, 2, 3, 4, 5}; // 错误 {}初始化只能在定义时使用
定义后数组名就是个常量,不能被赋值。所以必须要逐个元素来赋值
b.. int n = 5;int a[n] = {1, 2, 3, 4, 5}; //错误
元素个数必须为常量或常量表达式时才能在定义时初始化.如果是变量或变量表达式,不能初始化
但是可以这样:int a[n];a[0] = 1; a[1] = 2;
这样是可以的,注意这样就不是初始化了,没有赋值的元素的值不是0,而是任意数.
数组元素的赋值
a[0] = 1;a[1] = 2;
注意:
如果数组经过{}初始化后,没有被主动赋值的元素值为0.如果是在定义后逐个赋值,没有被主动赋值的元素值可能为任意值.
5.数组中的地址及元素
数组的地址和它的每个元素的地址
a.数组中的元素在内存中按照由小到大的地址排列
b.数组的地址是它的起始地址(最小地址),等于数组名的值
c.可以使用 prinf("%p", &a[i]);来查看元素/数组在内存中的地址
6.字符串注意点
a.char name[10] = {'a', 'b'};
也是一个字符串,因为字符数组默认后面的值都是0 (即'\0')
b.但是
char name[2] = {'a', 'b'};
char name[] = {'a', 'b'};就不是字符串了,因为它们只有两个元素,不以\0结束.
字符串都是字符数组,但不是所有的字符数组都是字符串.
c.通常还是使用双引号来定义
char name[10] = "Jack"; //使用双引号会在末尾自动添加'\0'
char name[] = "Jack"; //可以不指定数组大小
用数组形式s[]定义的是字符串变量,可以像数组一样访问,可以修改字符串的内容,比如s[0] = 'A'。
用指针形式*p定义的是字符串常量,不可以修改字符串的内容(比如p[0] = 'A';或 *p = "ABC";),但是可以指向一个新的字符串(比如 p = "ABC";),也可以指向一个可变字符串,比如p = s;就可以修改这个字符串中的内容了 p[0] = 'A'; 如果再次指向一个新定义的字符串(比如 p = "abc"),那还是字符串常量,不可修改。
7.结构体的内存
a定义结构体类型时,不会在内存中分配存储空间。定义结构体变量时会在内存中给它分配存储空间用于存放它的属性值。
b.一个结构体变量所占用的内存大小大约等于它各个属性的内存大小之和。会补齐为占用内存最大的属性所占空间的整数倍。( 补齐算法 )
8.关于预处理中的宏 #define 宏名 值 把这行代码后所有的宏名替换为它的值 (字符串中的不会被替换)
9.关于与处理中的文件包含
可以重复包含,这个可以用import或者#if来避免,但只是影响效率,不会影响编译,但是循环(互相)包含则是要报错的
10.类和对象中到底有什么
类中只存储方法列表。对像中包含成员变量和isa
11.super使用场合
使用场合: 子类重写父类的方法时想保留父类原有的行为.
12.initwith来赋值的时候注意
一定要注意格式if (self = [super initwith...])
{ _name =name;
}
如果有继承,通常只给自己的成员变量直接赋值, 父类的成员变量通过调用父类的初始化方法对其赋值
13.@class使用场景
使用场景对于循环依赖关系来说,比方A类引用B类,同时B类也引用A类,使用#import代码编译会报错。当使用@class在两个类相互声明,就不会出现编译报错
14.
int a = 10;
b = a++; 这个时候b是10,a是11,先赋值再计算a
如果是b = ++a,那b就是11,因为是把++a之后的值给b的。
15.递归的应用
前n项的和或者b的n次方
int pow1(int a, int n)
{
if (n < 1)
{
return 1;
}
return pow(a,n-1) * a;
}
int sum1(int n)
{
if (n == 1)
{
return 1;
}
return n + sum1(n - 1);
}