优秀的编程知识分享平台

网站首页 > 技术文章 正文

C语言,基本数据类型,字符串、数组和指针,预处理指令,代码

nanyue 2024-09-04 10:05:28 技术文章 4 ℃

一、数据类型

在C语言中,数据类型指的是用于声明不同类型的变量或函数的一个广泛的系统。变量的类型决定了变量存储占用的空间,以及如何解释存储地位模式。

1、基本类型,属于算术类型,整数类型和浮点类型。

2、枚举类型,属于算术类型,用来定义在程序中只能赋予其一定的离散整数值得变量。

3、void类型,类型说明符表明没有可用的值。

4、派生类型,指针类型、数组类型、结构类型、共用体类型和函数类型。

程序代码

#include <stdio.h>
#include <float.h>
 
int main(int argc, const char * argv[]) {
    // -128 到 127 或 0 到 255
    char c1 = 'a';
    // 0 到 255
    unsigned char c2 = 'b';
    // -128 到 127
    signed char c3 = 'c';
    printf("char %d \n",c1);
    printf("unsigned char %d \n",c2);
    printf("signed char %d \n",c3);
    int i1 = 1;
    unsigned int i2 = 2;
    printf("int %d \n",i1);
    printf("unsigned int %d \n",i2);
    printf("int 存储大小 : %lu \n", sizeof(int));
    short s1 = 1;
    unsigned short s2 = 2;
    printf("short %d \n",s1);
    printf("unsigned short %d \n",s2);
    long l1 = 1;
    unsigned long l2 = 2;
    printf("long %d \n",l1);
    printf("unsigned long %d \n",l2);
 
    float f1 = 0.1234;
    double d1 = 0.12345678;
    long double d2 = 0.123456789123456789;
    printf("float %E\n",f1);
    printf("float 存储最大字节数 : %d \n", sizeof(float));
    printf("float 最小值: %E\n", FLT_MIN );
    printf("float 最大值: %E\n", FLT_MAX );
    printf("精度值: %d\n", FLT_DIG );
    printf("double %E\n",d1);
    printf("long double %E\n",d1);
     
    return 0;
}

sizeof()函数,计算数据(数组、变量、类型、结构体等)所占空间,用字节数表示。

程序输出

char 97 
unsigned char 98 
signed char 99 
int 1 
unsigned int 2 
int 存储大小 : 4 
short 1 
unsigned short 2 
long 1 
unsigned long 2 
float 1.234000E-01
float 存储最大字节数 : 4 
float 最小值: 1.175494E-38
float 最大值: 3.402823E+38
精度值: 6
double 1.234568E-01
long double 1.234568E-01
Program ended with exit code: 0

二、字符串、数组和指针

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。

*p:一级指针,表示p所指向的地址里面存放的是一个类型的值。

**p :二级指针,表示p所指向的地址里面存放的是一个指向类型的指针。

空指针和野指针

在函数内部对指针进行赋值操作后,在函数执行完毕后,该指针就成了一个空指针(变量从栈中弹出)。但是通过动态地址分配(堆空间)的指针不会有上述问题。

free(p)后释放内存的指针为野指针。

const在int的左边那就是不能修改地址中的值,在右边就是不能指向其他地址,左右都有那就是既不能修改地址的值也不能指向其他地址。

程序代码

#include <stdio.h>
 
/**
 主函数
 @param argc argc description
 @param argv argv description
 @return return value description
 */
int main(int argc,const char* argv[]){
    //一维字符数组
    char a[10];
    //二维字符数组
    char b[5][10];
    //给部分数组元素赋值
    char c[20]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a','m'};
    //对全体元素赋值时可以省去长度
    char d[]={'c', ' ', 'p', 'r', 'o', 'g', 'r', 'a', 'm' };
     
    //可以将字符串直接赋值给字符数组
    char str1[30] = {"www.what21.com"};
    char str2[30] = "www.what21.com";
    char str3[] = {"www.what21.com"};
    char str4[] = "www.what21.com";
    // 用字符串给字符数组赋值时由于要添加结束符 '\0',
    // 数组的长度要比字符串的长度(字符串长度不包括 '\0')大1。
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    printf("str3: %s\n", str3);
    printf("str4: %s\n", str4);
     
    //i1取地址(&)将值赋给指针i2,也就是说这个指针i2指向i1。
    int i1 = 10;
    int *i2 = &i1;
    printf("i1=%d\n",i1);
    // 结果是一个地址
    printf("i2=%p\n",i2);
    // 输出实际结果
    printf("i2=%d\n",*i2);
    // 结果是一个地址(指针的地址,因为指针也是一个变量自己也有地址的)
    printf("i2=%d\n",&i2);
     
    //数组名是一个地址,它可以被理解为一个常指针
    //它只能指向本数组首元素的地址,而指针可以指其他的变量等等。
    int string[5]={1,2,3,4,5};
    int *p=string;
    //输出为1,数组的首元素。
    printf("%d\n",*p);
    //输出为1,数组的首元素。
    printf("%d\n",*string);
    //输出为1,数组的首元素。
    printf("%d\n",string[0]);
    //输出为地址,数组的地址。
    printf("%p\n",p);
     //输出为地址,数组的地址。
    printf("%p\n",string);
    //输出为2,数组的第二个元素。
    printf("%d\n",*(p+1));
     //输出为2,数组的第二个元素。
    printf("%d\n",*(string+1));
     
    char *month[] = {"January","February","March","April",
        "May","June","July","August","September","October",
        "November","December"};
    char *curMonth = month[4];
    printf("当前月份为:%s\n",curMonth);
    printf("当前月份为:%s<-%#X\n", curMonth, &curMonth);
     
    int aa=10,bb=20;
    //无法使p指向其他地址
    int *const pp=&aa;
    //pp=&bb; -> 这样的操作是不允许的。
    *pp=20; //可以这样操作。
    printf("%d\n",*pp);
    printf("%#X\n",pp);
     
    const int *ppp=&aa;     //p可以指向其他地址。
    ppp=&bb;                      //可以操作。
    //*p=10;  操作不被允许。
    printf("%d\n",*ppp);
    printf("%#X\n",ppp);
     
    //p不能指向其他地址,也不能改变地址中的值。
    const int * const pppp=&a;
    //操作不被允许 p=&b;
    //操作不被允许 *p=20;
    printf("%d\n",*pppp);
     
    int x=10;
    int *y=&x;
    int **z=&y;
    printf("y=[%d]\n",*y);
    printf("z=[%d]\n",**z);
     
    return 0;
}

三、预处理指令

预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。

程序代码

#include <stdio.h>
 
#define MAX_ARRAY_LENGTH 20
 
#define FILE_SIZE 84
#undef  FILE_SIZE
#define FILE_SIZE 42
 
#ifndef DOMAIN
#define DOMAIN "www.what21.com"
#endif
 
//defined() 运算符
#if !defined (MESSAGE)
#define MESSAGE "www.what21.com~!"
#endif
 
//标记粘贴运算符(##)
#define pasterToken(n) printf("token" #n " = %d\n", token##n)
 
//参数化的宏
#define MAX(x,y) ((x) > (y) ? (x) : (y))
 
/**
 主函数
 @param argc argc description
 @param argv argv description
 @return return value description
 */
int main(int argc,const char* argv[]){
    printf("%d\n",MAX_ARRAY_LENGTH);
    printf("%d\n",FILE_SIZE);
    printf("%s\n",DOMAIN);
     
    //字符串常量化运算符(#)和标记粘贴运算符(##)。
    int token34 = 40;
    pasterToken(34);
     
    printf("%s\n", MESSAGE);
    printf("Max between 20 and 10 is %d\n", MAX(10, 20));
     
    printf("File :%s\n", __FILE__ );
    printf("Date :%s\n", __DATE__ );
    printf("Time :%s\n", __TIME__ );
    printf("Line :%d\n", __LINE__ );
    printf("ANSI :%d\n", __STDC__ );
     
    return 0;
}
最近发表
标签列表