Giskard

(三十九)语法杂项

2018-11-01

变量总是有值的

变量总是有值的,即使你没有初始化。变量的值就是内存的值,内存里每个位的值要么是1要么是0,总有一个值。当一个变量被声明而未初始化时,它的值称为原始值或随机值。

一般如果一个变量没有赋值,想要打印就会报错。其实这只是辅助检查错误的模式而已。在生成->配置管理器->将Debug改为Release,就不会报错了。

在Debug编译模式下,程序包含了一个辅助调试信息,才会出错。

在Linux下,使用-g编译表示Debug模式

typedef的用法

用于给已有的类型声明一个别名,确切的说,不是定义一个类型,而是定义一个类型的别名。

#include<stdio.h>
typedef unsigned int UINT32;
int main()
{
    UINT32 a;
    UINT32* p = &a;

    unsigned int b;
    p = &b;
    return 0;
}

这种只是写法的简化而已

在旧的C语法中,struct用起来比较麻烦,一般用typedef进行简化

//C语言写法
struct Student
{
    int id;
    char name[16];
}
//建立Student对象,需要加上Student
struct Student s;

//建立Student对象,使用typedef简化
typedef struct Student student_t;
student_t s;
//C语言使用typedef,更大的简化
typedef struct
{
    int id;
    char name[16];
}Student;

Student s;

名字太长的模板类

#include<list>
struct Student
{
    int id;
};

typedef list<Student> StudentList;

typedef和#define相比

typedef unsigned int UINT32;

#define UINT32 unsigned int

不推荐使用宏定义#define,宏定义是预编译过程,typedef是编译。宏定义只是文本替换,typedef是完全代表了unsigned int

main函数之前的函数

我们知道main函数是程序的入口,第一个被执行的函数,而在引入构造函数后,事情发生了变化。

定义一个class类型的全局变量,则全局变量的构造函数会先于main函数被执行

#include<stdio.h>
class Object
{
public:
    Object()
    {
        printf("created!\n");
    }
};
Object obj;
int main()
{
    printf("...\n");
    return 0;
}

如果定义了多个全局变量,很难确定哪个先被构造,哪个后被构造。所以尽量不使用全局变量,如果一定要使用,则要保证其构造函数不要太复杂。

绝对路径、当前路径、相对路径

绝对路径又叫全路径,C:/windows/system32/abc.dll

当前路径,指的是程序的工作目录,当一个文件只有名字没有目录的时候,表示在当前程序(.sln文件所在)目录下创建

const char* filepath = "abc.txt";
FILE* fp = fopen(filepath,"wb");

在哪里运行exe文件,生成的abc.txt就在哪里。vs里可以在项目属性调试里面设置工作目录

在程序里可以手工写代码调整工作目录

#include<windows.h>
SetCurrentDirectoryA("D:\\test\\cpp");

相对路径

工作目录为D:/cpp/hello

“output/abc.txt”即为D:/cpp/hello/output/abc.txt

“./output/abc.txt”即为D:/cpp/hello/output/abc.txt,点号表示在本目录

“../abc.txt”即为D:/cpp/abc.txt,..表示在上层目录

“../../abc.txt”即为D:/abc.txt

数组的特殊用法

数组:若干连续的元素,在内存上也是连续的

数组名:这一块内存的首地址

#include<stdio.h>
void test(int arr[],int len)
{
    int n = sizeof(arr);  //值为4,此时它计算的是int arr[]的大小,是int类型的,故为4
    printf("%d\n",n);
}

int main()
{
    int arr[5]={1,2,3,4,5};
    test(arr,5);
    return 0;
}
int arr[5]={1,2,3,4,5};
int n = sizeof(arr);//值为20

int arr[5]={1,2,3,4,5};
int* p = arr;
int m = sizeof(p);//值为4

作为数组变量时,得到的是正确的大小,作为函数参数时,只是一个普通的指针变量而已,就是4。

二维数组的用法

int arr[2][4] = 
{
    {1,2,3,4},
    {5,6,7,8},
};

数组名就是地址,二维数组的数组名是否也可以传地址呢?

void test(int data[][4],int rows)
{
    for(int i=0;i<rows;i++)
    {
        for(int j=0;j<4;j++)
        {
            printf("%d",data[i][j]);
        }
    }
}
int main()
{
    int arr[2][4] = 
    {
           {1,2,3,4},
        {5,6,7,8},
    };
    test(arr,2);
}

或者(不推荐)

void test(int (*p)[4],int rows)
{
    for(int i=0;i<rows;i++)
    {
        for(int j=0;j<4;j++)
        {
            printf("%d",p[i][j]);
        }
    }
}
int main()
{
    int arr[2][4] = 
    {
           {1,2,3,4},
        {5,6,7,8},
    };
    int (*p)[4] = arr;
    test(arr,2);
}

头文件的搜索目录

把Object结构体定义放在Object.h文件,在main.cpp使用

#include<stdio.h>
#include "Object.h"

为什么一个尖括号一个双引号

尖括号表示从标准目录搜索该文件,双引号表示先从当前目录搜索该文件,再从标准目录搜索

Tags: C/C++