C语言基础?

先推荐几个网站:

修饰符

C语言中有int float double char bool这几个常见的数据类型,而对一个变量而言,除了数据数据外,还有修饰符。

  • const: 限定一个变量不允许被改变,相当于 readonly 。
  • extern: 就是在任何函数的外部定义的变量,具有“全局型“定义。全局变量也是外部型。要访问其他文件中的外部型变量前需使用extern声明。
  • static: 分内部静态变量和外部静态变量,内部静态变量即在函数内部定义的变量,作用域类似于auto,仅在当前函数内部有效,不同在于函数退出后,值仍然有效。通过将变量设为外部静态型可将文件中的函数或变量隐藏,不允许别的文件存取,与extern相对。
  • auto: 声明为自动型变量,在函数内部声明的变量默认都是自动型(前提是不加static等),作用域仅限当前函数。
  • volatile: 确保本条指令不会因编译器的优化而省略。
  • register:尽可能的将变量存在CPU 内部寄存器中以提高效率。

上面的内容都是百度百科中摘抄的,重点关注const extern static auto,其他2个很少见。

指针

  • & 取地址
  • * 取出地址中的值

指针变量

int a = 65;    // a 的地址为0x0000FF7C
int addr = &a; // 会有警告

// *(&a) 输出为 65
// *addr 输出为addr保存的值 0x0000FF7C 
// (int *)addr 将 0x0000FF7C 当地址对待
// *(int *)addr 输出 65

int *p = &a; // p 保存的值为 0x0000FF7C 
// *p 输出的值为 65

所以指针变量就是保存某个变量地址的一个变量,在使用*取值时,它会取保存的地址上的值。

而且,指针是一个用来保存指向变量的地址值的变量,地址的长度都是一样的,所以各种类型的指针所占的内存大小是一样的。

#include <iostream>
using namespace std::cout;
int main() {
    int a = 1;
    int b = 2;
    int c = 3;
    int *p = &c;
    
    cout<<&c<<"\n"<<&b<<"\n"<<&p<<"\n";
    cout<<c<<"\n"<<p<<"\n"<<*p<<"\n";
    for(int i=0; i<3; i++ ) {
        cout<<*p<<"  "<<"&p:"<<&p<<"p:"<<p<<"\n";
        p++;
    }
    return 0;
}

运行结果如下:
0x7ffdeb944910
0x7ffdeb944914
0x7ffdeb944908
3
0x7ffdeb944910
3
3     &p:0x7ffdeb944908   p:0x7ffdeb944910
2     &p:0x7ffdeb944908   p:0x7ffdeb944914
1     &p:0x7ffdeb944908   p:0x7ffdeb944918

可知变量的地址是降序分配的,指针p本身的存储地址没有变化,但它保存的值(地址)在变化。

对指针分配空间

可用malloccalloc函数,calloc分配时会将所分配字节置0,而malloc仍是原始的随机值。用法示例如下:

int a[8];
int *p = (int *) malloc(sizeof(int) * 8);

int b[8] = {};
int *q = (int*) calloc(8, sizeof(int));

free(p);
free(q);

注意上面malloccalloc函数用法不同,而且在使用这种方法分配空间后,要手动释放空间,使用free函数。

如果要改变上面分配的空间的大小,可以使用realloc函数,此函数会使原空间的值保持不变。用法realloc(p, sizeof(int)*10), 建议使用c++ reference查看函数具体说明。

对指针使用const限定符

指向常量的指针

如果要让指针指向常量,就要声明一个指向常量的指针;

const int a = 1, b = 2;
int c = 5;  
const int *p = &a;
int *q = &a;    // error!! 非常量指针指向常量会报错

*p = 3;     // error!! 常量指针即不允许对值进行修改
p = &b;     // 可改变p保存的地址值。
p = &c;     // 常量指针可指向非常量
*p = 3;     // error!! 常量指针不允许通过*p来修改值

常量指针

int a = 1, b = 2;
int * const p = &a;
*p = 3;     // 正确
p = &b;     // error!! 常量指针不允许修改保存的地址

void指针

void指针可以指向任何变量,不过不可使用*p来取值,必须通过强制转换赋值给相应数据类型的指针进行操作。

int a = 1, *p;
void *vp = &a;
p = (int *)vp;
cout<<*p;

数组

数组的初始化

如果定义时只对数组元素前几个初始化,则其他元素初始化为0;若未进行初始化,则:

  1. 外部型和静态型初始化为0;(即全局变量和externstatic);
  2. 寄存器型(register)和自动型(auto)初始为随机数;
#include <stdio.h>
int x[6];           // 外部型变量,初始化全为0
int main() {
    int a[5] = {1, 2};  // 其余项为0
    int b[6] ;          // auto 型,为随机数
    b[6] = {1, 2, 3};   // error!! 使用{}初始化只能在声明时使用,这里b[6]是数组的第7个元素,还越界了...
    int c[6] = {0};     // auto 型,全为0
    char s[] = "hello!";// s占7个字节,最后一个为`\0`;
    char cs[7];
    for( int i=0; i<7; i++ ) {
        cs[i] = s[i];   // copy 时要将最后一位`\0`也要复制
    }
}

字符串常量

char s[] = "hello!", *p = "hey", *s;
s = "hi!!";     // *p 与 *s 指向的字符串为常量(const)
p[1] = 'i';     // error!! 不可更改
s[1] = 'e';     // error!! 不可更改
s++;
cout<<s;        // 输出 "i!!" 值不可更改但指针可移动

指针数组

每一个元素都是一个指针;

char *p[] = {"dog", "cat", "fish"};

二维数组

// 初始化
int a[2][3] = { {1,2,3}, {4,5}};    // a[1][2] = 0
int b[2][3] = {1, 2, 3, 4, 5};      // 同上, a==b
int c[][3]  = {1, 2, 3, 4, 5};      // 同上, a==b==c

// 指针与数组
int *p;
p = a;          // error !! a代表一维数组名
p = &a[0][0];   // 不推荐
p = a[0];       // 推荐 p[0]=a[0][0], p[1]=a[0][1], p[3]=a[1][0];


// 指向一维数组的指针
int (*q)[3];    // q为指向一维数组的指针
q = a;          // 正确 p[0]=a[0] p[0][1]=a[0][1] **p = a[0][0]=*p[0]
q=a[0]          // error !!
// *(*(p+i)+k) = p[i][k]

函数

main函数原型

int main(int argc, char *argv[]); 

char *argv[]定义了一个指针数组,将上述程序生成可执行文件名为test,输入命令test argc1 argc2 argc3。那么argv[0] = test, argv[1] = argc1

枚举 enum

enum alpha{A,B,C,D=5,F};

int main() {
    int a=1;
    enum alpha e = A;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值