【C语言篇】☞ 12. 关键字、字符串面试题

全局变量

  全局变量定义在函数体外部(包括main函数)的变量。全局变量的作用域是本文件,在其它文件要使用这个变量需要重新声明。

  • 使用 extern 关键字声明另一个文件定义的全局变量。

    extern int global; //声明一个全局变量。相当于告诉编译器,你别管啦,这是个全局变量,我保证他是存在的。

  • 全局变量有风险,谨慎定义,因为任何人都能修改它的值。    

    static int global = 200; //全局静态变量(静态的只允许本文件内部访问)

  • 全局变量的生命周期是整个程序运行期间。全局变量没有初始化时,其值为0,浮点型是0.0,布尔类型是false0

局部变量

1)定义在函数内部(包括:函数的参数、ifforwhile里面定义的变量)

2)定义在复合语句(代码块{……})中

  • 默认的局部变量(也叫自动变量):

    auto int a; //由关键字auto声明,可以省略。内存空间是自动分配,(出了作用域)自动释放!

  • 静态局部变量:

    static int a; //变量a在全局区分配空间,函数结束时候,内存不会释放。

※ 不管调用函数多少次,这条语句只执行一次,即第一次执行,内存空间不受函数的控制。

静态局部变量的生命周期和全局变量一样,都是整个程序运行期间!

局部变量在没有初始化的情况下是一个随机数据(垃圾值)

auto关键字

auto int x;//自动变量,局部变量(auto默认省略)

auto 只能修饰局部变量,不能修饰全局变量!

static关键字

  1. 修饰局部变量:生命周期变长(整个程序运行期间),作用域不变(和普通变量一样)

          static修饰的局部变量,其数值就是上一次函数调用结束之后的数值!

          扩展(用途):可以记录一个函数被调用了多少次!

//计数器函数,记录被调用的次数

int count() {

    static int cnt = 0; //不管调用多少次函数,这条语句只会执行一次

    cnt++;

    return cnt;

}

   

  2. 修饰全局变量:只能在本文件内部访问,其它文件不能访问。保护全局变量。

  //静态的只允许本文件内部访问

  static int global = 200;//全局静态变量

 

3. 修饰函数:也是只能在本文件中访问,其它文件都不能访问!

//此函数为私有函数,只允许本文件内部调用,别的文件中无法调用

static void func(){

    printf("这是本文件内部函数,其它文件中无法! ");

}

 

  举例:使用static修饰局部变量,查看特性。

   

  对比之下,可以看出使用static修饰的局部变量的特性,访问范围和普通的局部变量一样,但是在函数执行完毕之后其数值并不会释放。

   

const关键字

  const修饰的变量:只读变量(常量),不可修改变量的数值!

  

  

register、volatile

//寄存器变量,仅仅是申请一下,编译器不一定批准

register int x = 10;//CPU, 理论上存取速度非常快

//易变的变量,编译器读取时不要做优化处理,除非在嵌入式开发中使用传感器改变变量的值时  

volatile int y = 20;

 

使用 extern 关键词声明另一个文件定义的全局变量

extern int global; //声明一个全局变量。相当于告诉编译器,你别管啦,这是个全局变量,我保证他是存在的。

extern void sum(); //外部函数的声明

static void minus(); //内部函数的声明

 

字符串面试题

/**

 *  实现字符串常用的4个库函数

 */

#include <stdio.h>

#include <assert.h>

/** 实现strlen函数 */

int mystrlen(char *arr) {

    int count = 0;//定义变量记录取出了多少个字符

    while(arr[count] != '') {

        count++;

    }

    return count;

}

/** 实现strcat函数 */

char *mystrcat(char *str1, const char *str2) {

    char *tmp = str1;

    while(*str1)

        str1++;

    while((*str1++ = *str2++) != '');

    return tmp;

}

/** 实现strcpy函数 */

char *mystrcpy(char *str1, const char *str2) {

    assert(str1 != NULL && str2 != NULL);//断言函数,检查参数的有效性(防错设计)

    char *tmp = str1;

//*str2*str1逐个字符进行赋值

//*str2直到把''赋值给*str1时,*str1的结果就是0,循环就结束!

    while((*str1++ = *str2++));

    return tmp;

}

/** 实现strcmp函数 */

int mystrcmp(char *str1, char *str2) {

    assert(str1 != NULL && str2 != NULL);

    while(*str1 == *str2 && *str1 != '') str1++, str2++;

    if(*str1 > *str2) {

        return 1;

    } else if(*str1 < *str2) {

        return -1;

    } else {

        return 0;

    }

}

int main() {

    char str1[] = "hello";

    char *str2 = "world";

    printf("%d ", mystrlen(str1));//str1的长度为:5

    printf("%s ", mystrcat(str1, str2));//拼接后:helloworld

    printf("%s ", mystrcpy(str1, "ABCDE"));//拷贝(覆盖)ABCDEF

    printf("%d ", mystrcmp(str1, str2)); //-1(str1 < str2)

    return 0;

}

  

//字符串赋值(拷贝)

void Strcpy(char *s1, const char *s2)

{

    //while(*s1++ = *s2++);

    while (*s2 != '') {

        *s1 = *s2;

        s1++;

        s2++;

    }

    *s1 = '';

}

//字符串连接

void Strcat(char *s1, const char *s2)

{

    while(*s1)s1++;

    //while(*s1++ = *s2++);

    while(*s2){

        *s1 = *s2;

        s1++;

        s2++;

    }

    *s1 = 0;

}

//字符串长度

int Strlen(const char *str)

{

    int cnt = 0;//保存结果

    while (*str) {

        cnt++;

        str++;

    }

    return cnt;

}

//字符串比较

int Strcmp(const char *s1, const char *s2)

{

    while(*s1 || *s2){

        if(*s1 > *s2)  return 1;

        else if(*s1 < *s2) return -1;

        s1++;

        s2++;

    }

    return 0;

}

  

  

有一个字符串"abcd1234",请写一个函数,将此字符串拆成两部分, abcd保存到char str[10]中,1234保存到变量int x中:

int str2int(char *str, char *s){

    //....

}

int main()

{

    char *source = "abcd1234";

    char str[10] = {0};

    int x = 0;

    x = str2int(cource, str);

}

 

原文地址:https://www.cnblogs.com/bossren/p/6407024.html