一直用php编程,回头学习C和C++。php核心也是基于C开发的,也能使用C来写php的拓展,记录下从脚本语言到底层语言的学习中,会有多少需要注意的部分。
//1.
char name = 'a';//在使用单字符
char name = 97;//在使用字符型变量,赋值没有用引号包含,则视为ASCII码,ASCII码97为字符a
//2.
float num1 = 12345678;//浮点型和双精度浮点型在内存中以1.2345678E7的科学计数法保存,
//其中float型有效精度为7位,也就是实际上只能保存位为1234567?,造成末位的数字丢失
//3.
if
printf('first line code');
printf('second line code');//在if结构中,如果省略了if后的大括号{},则此行代码不会执行
else
//do sth
//4.定义使用数组
int arr[5] = {1,2,3,4,5};//最多可以引用arr[4],arr[6]等超过指定下标引起过界,擦写了未知未知的内存
printf('%s',arr);//将会打印数组和乱码,打印数组内容后,需要碰到\0才停止打印,arr中没有\0,会一直打印乱码直到内存中遇上\0,如果数组内有多个\0,则第一个\0就停止打印
arr = 5;//报错,无法给整个数组赋值
int arr[3][4];//定义二维数组
int myindex = 5;
int arr2[myindex];//无法使用变量初始化数组
char three[3] = "abc";//报错,字符串abc由 abc 和 \0构成,因此数组长度至少为4
//5.scanf获取字符串
char arr[100];
scanf(‘%s’,arr);//最多输入99个字符,留一个位置给回车后自动为字符串补全的\0
printf('%s',arr);//如果arr在scanf中输入超过了99个字符,将会造成arr数组越界
//6
char aa = 'a';
char bb = 'a';
if(aa == bb)//不相等,比较的是变量的内存地址,比较字符/串相等用strcmp函数
//7//函数在调用时,提示不存在,可以先声明再定义
void printHello();//先声明
main(){
printHello;//调用
}
void printHello(){//定义
printf("hello world");
};
//8
int myNums[2] = {1,2};
void changeValue(int nums[]){
nums[0] = 3;
nums[1] = 4;
}
changeValue(myNums);//myNums值被改变,C中传变量名时使用地址传递,相当于php中的绝对引用
int myArrNums[2][2] = [{1,2},{3,4}];
void changeArrNumsValue(int nums[][2]){//多维数组时,省略一维大小,但是二维和以上需要指定大小
//...
}
//9.1
extern int c1;//预先提示后方出现了c1的定义
void myfun(){
//extern int c1;//只在该函数中有效,不常用
printf(c1);//预先提示后才可以使用后方定义的全局变量
}
int c1 = 1;
//9.2
#first.cpp
extern int c1;
printf("%d",c1);//extern可以声明使用同一个项目,其他文件里的变量,必须在所有函数之前。
//函数则需声明 void myfun();
/*void myfun(){
extern int c1;//错误,函数内的局部声明,无法跨文件访问其他文件里的变量
}
*/
#second.cpp
int c1 =1;
//9.3
//文件内的static变量、函数,只能被本文件引用
//10
int number;//number的值不确定
static int numbe;//值为0
//11
一个解决方案->多个项目
一个项目->多个cpp文件->只能有一个main函数->生成一个.exe文件
//12.1 define,也就是宏的语句结尾不需要加分号
//12.2 define multipi(a,b) a*b //最好写成(a)*(b),防止传入的是表达式
//13 按条件编译
#ifdef
#if
#else
#endif
#endif
//14.1 指针,&为地址符
int p = 1;
int *p_neddle = p;//声明指针,并指向变量p,*p_neddle 等同 p,修改*p_neddle 等同修改 p
int *p_neddle2;
//14.2
p_neddle2 = &p;//分行写法,令指针变量*p_neddle2 的指针p_neddle2等于p的指针;
*p_neddle2 = &p;//错误 ,指针变量 = 变量信息 (其中包含:值/地址信息),地址是变量的子集,变量不能被自己的子集赋值;
int arr[2]={1,2};//在给指针变量赋值中,数组的名字等同于数组开始地址(&arr写法使用arr 替代)
int *arr_neddle;
arr_neddle = &arr[0];
//14.3
arr_neddle+1;//指的是,整型指针变量的内存地址(用十六进制记录存储:0x00..d8),每个整型类型在记录中用4个字节,即下个邻近的整型内存块的开始地址为0x00...d8加4,为0x00...ec,在一维数组中元素的内存是邻近分配的,也就是arr_neddle+1等同(&arr[0])++等同&arr[1]
int arr2[2][2];
int *arr_neddles = arr;
//14.4
arr_neddles ++;//指针地址自增一个单位,这里arr_neddles指向一个二维数组,共计4*4个长度,所以内存地址自增16
int *p_neddle2;
*p_neddle2 = 1;//错误,指针变量还未指向/分配合法内存地址,不能给非法的内存地址赋值
*p_neddle2 = &p;//错误,正确的指针赋值p_neddle2 = &p;
printf("%d",*p++);//*p++等同*(p++),先打印*p,然后p指向下一块内存
//字符串指针变量指向的是开始地址,无法进行增减并赋值操作
//14.5 void *neddle;//万能型指针变量
//14.5 其他关于函数指针的用法
//15
//NULL 指向内存地址为0x000000,系统会保证这个内存地址不存放有效数据
//16结构体
//定义结构体类型
struct date{
int year;
int month;
int day;
} ;//分号必须有
struct student{//student 为结构体名
char name[100];
int age;
struct date birth;//结构体类型成员
} bob,wendy;
//
struct student bily;//使用结构体类型新建一个实例
struct student students[50];//结构体数组
//17.1 共用体 不同类型的变量,先后擦写存于同一段内存中
union myuni{
int carnum;//4字节
int cartype;//4字节
char carname[60];//60字节
}
//17.2 共用体所占内存为60个字节,如果是结构体,那就算60+4+4个字节
//17.3 同一时刻,共用体有一个成员生效,给共用体赋值车牌号、车型和名称,只有最后的名称保存下来。所以共用体基本是成员只能为一个的结构体。因为只能存一个,所以不能初始化的时候给三个成员赋值。
//17.4 因为是反复擦写一块内存,共用体赋值过程中开始地址一样的。
//18 枚举类型
enum color{
yellow ,//将被赋值为0
red = -1,
green = 6,
black//枚举常量,4个字节、类似整型常量
}
//18.2 使用定义好的枚举类型
enum color mycolor1,mycolor2;//能使用color枚举类型的枚举常量
mycolor = green;//用常量给变量赋值
//19 typedef 定义类型
typedef int NUM[100];//定义一个长度为100的整型数组为一个新的类型NUM
NUM a,b;//定义长度100的整型数组a和b
//20
//结构体可以写入文件,但是结构体不能包含指针,在重新读取运行后指针就没有意义。
//vs win gcc和linux gcc编译器上,为了程序效率会进行结构体对齐,其中vs上是对齐8字节,linux是4字节,保存和读写会发生字节错位。需要保存的结构体时要定义为1字节对齐结构体
#pragma pack(1)
struct stu {
char name[30];
int age;
}
#pragma pack()