C语言入门(一)

1、c语言代码结构
c文件以.c结尾。

#include <stdio.h> // 导入标准库,C99标准库
// <>代表寻找系统的资源
// ''代表寻找我们自己写的资源
// .h结尾代表声明c语言头文件, .hpp结尾代表声明c++语言头文件
// .c结尾代表实现c语言文件,   .cpp结尾代表实现c++语言文件
int main() {
    printf("哈哈 Hello, World!");

//    getchar(); // getchar()会阻塞,使程序一直处于运行状态
    return 0;
}

多个类不能有多个main方法,运行会报错。

FAILED: CProject 
: && /Library/Developer/CommandLineTools/usr/bin/cc -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/CProject.dir/T1.c.o CMakeFiles/CProject.dir/T2.c.o -o CProject   && :
duplicate symbol '_main' in:
    CMakeFiles/CProject.dir/T1.c.o
    CMakeFiles/CProject.dir/T2.c.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

2、基本数据类型占位
C语言中不能直接打印,需要使用占位。

int main() {
    int i = 10;
    double d = 10;
    float f = 10;
    long l = 10;
    short s = 10;
    char c = '1';
    
    // 字符串 用 char * 表示
    char *str = "字符串";
    
    // printf(i); // 直接写的话,是不会打印的。
    
    // 需要通过占位。
    // int long short 可以直接通过 %d 占位
    printf("打印的是int %d\n", i);
    printf("打印的是long %d\n", l);
    printf("打印的是short %d\n", s);

    // double 通过 %lf 占位(相当于long float),float 通过 %f 占位
    printf("打印的是double %lf\n", d);
    printf("打印的是float %f\n", f);

    // char 通过 %c 占位
    printf("打印的是char %c\n", c);

    // str 通过 %s 占位
    printf("打印的是string %s\n", str);
}

3、基本数据类型占用的字节数

int main() {
    // sizeof可以获取字节数
    printf("int占字节数 %d\n", sizeof(int));
    printf("long占字节数 %d\n", sizeof(long));
    printf("short占字节数 %d\n", sizeof(short));
    printf("double占字节数 %d\n", sizeof(double));
    printf("float占字节数 %d\n", sizeof(float));

    printf("char占字节数 %d\n", sizeof(char));

    //int占字节数 4
    //long占字节数 8
    //short占字节数 2
    //double占字节数 8
    //float占字节数 4
    //char占字节数 1
    return NULL;
}

4、在 C、C++ 语言中,万物皆指针( 指针 = 地址 )

int main() {
    // 万物皆地址
    int i = 1000;
    // 地址用占位符 %p 占位。 在对象前面加 & 表示,取出对象的内存地址
    printf("打印int 1000的地址 %p\n", &i); // 结果:打印int 1000的内存地址 0x7ff7bb35f43c,每次打印的地址不一样,由c/c++分配
    int num_int = 1000;
    double num_double = 2000;
    printf("直接获取值 num_int=%d\n", num_int);
    printf("直接获取值 num_double=%lf\n", num_double);

    // &num_int 取出num_int的内存地址,
    // 在内存地址前面加*,代表取出内存地址上对应的值
    // *&num_int 取出&num_int这个内存地址上对应的值
    printf("通过地址获取值 num_int=%d\n", *&num_int);
    printf("通过地址获取值 num_double=%lf\n", *&num_double);

    // 这里不是定义一个int对象,而是定义一个int *对象(int类型的内存地址对象)。
    int *num2_intP = &num_int;
    double *num2_doubleP = &num_double;
    // 在内存地址前加*,取出值
    printf("num2_int=%d\n", *num2_intP);
    printf("num2_double=%lf\n", *num2_doubleP);

    // 内存地址变量、内存地址别名、指针、指针变量、指针别名...分别指啥?
    // 以 int *num2_intP = &num_int; 为例,
    // 内存地址 == 指针,int *
    // 指针别名 == 指针变量(指针的变量),num2_intP
}

5、通过指针去修改值

int main() {
    int i = 100;
    // 1、直接修改
    i = 200;
    printf("i的是值是%d\n", i);

    // 2、通过指针修改
    int *ip = &i; // ip就是i的内存地址
    *ip = 300; // 取出i内存地址上的值,然后把300赋值给它。
    printf("i的是值是%d\n", i);
}

6、函数声明的位置

// 2、必须定义在main方法之前
void change2(int i) {

}

// 3-1、如果还想定义在main方法之后,那必须在main方法之前声明,然后在后面实现
void change3(int i);

int main() {
    int i = 1000;

//    change(i);
    change2(i);
    change3(i);
}

// 1、会报错,不能在main方法后面声明。
//void change(int i){
//
//}

// 3-2:在后面实现
void change3(int i) {
}

7、函数变量的传递

void change(int i) {
    printf("change 改变前,i的值是 %d,i的地址是%p\n", i, &i);
    i = 2000;
    printf("change 改变后,i的值是 %d,i的地址是%p\n", i, &i);
}

int main() {
    int i = 1000;
    printf("main 调用change前,i的值是%d,i的地址是%p\n", i, &i);
    change(i);
    printf("main 调用change后,i的值是%d,i的地址是%p\n", i, &i);
}

打印结果:

main 调用change前,i的值是1000,i的地址是0x7ff7b7d6b43c
change 改变前,i的值是 1000,i的地址是0x7ff7b7d6b41c
change 改变后,i的值是 2000,i的地址是0x7ff7b7d6b41c
main 调用change后,i的值是1000,i的地址是0x7ff7b7d6b43c

可以看到,main方法中的i和change方法中的i的地址是不一样的。
这说明在调用change方法后,c编辑器相当于是复制了一份i,这也就解释了在change方法中改变了i的值,并不会影响main方法中的i值.

那我们要怎么实现改变同一个变量的值呢?

声明不允许函数重载,所以改个函数名
void change2(int *pInt) {
    printf("change2 改变前,i的值是 %d,i的地址是%p\n", *pInt, pInt);
    // 改变内存地址上的值。
    *pInt = 2000;
    printf("change2 改变后,i的值是 %d,i的地址是%p\n", *pInt, pInt);
}

int main() {
    int i = 1000;
    printf("main 调用change2前,i的值是%d,i的地址是%p\n", i, &i);
    // 传递i的内存地址
    change2(&i);
    printf("main 调用change2后,i的值是%d,i的地址是%p\n", i, &i);
}

打印结果:

main 调用change2前,i的值是1000,i的地址是0x7ff7b84a143c
change2 改变前,i的值是 1000,i的地址是0x7ff7b84a143c
change2 改变后,i的值是 2000,i的地址是0x7ff7b84a143c
main 调用change2后,i的值是2000,i的地址是0x7ff7b84a143c

可以看到,main方法中的i和change方法中的i的地址是一样的了。
在change2方法中,改变了同一地址的值后,main方法中的i值也随之改变。

两个值得互换

void change3(int *ip, int *jp);

// 两个值互换
int main() {
    int i = 10;
    int j = 20;
    // 传入i和j的内存地址
    change3(&i, &j);
}

void change3(int *ip, int *jp) {
    printf("change3前,i的值%d%,j的值%d,i的地址%p,j的地址%p\n", *ip, *jp, ip, jp);
    int tempI = *ip; // 定义一个临时的变量,用来记录i的值。
    *ip = *jp; // 将ip地址上的值修改成jp地址上的值。
    *jp = tempI; // 将jp地址上的值修改成ip地址上之前的值。
    printf("change3后,i的值%d,j的值%d,i的地址%p,j的地址%p\n", *ip, *jp, ip, jp);
}

打印结果:

change3前,i的值10,j的值20,i的地址0x7ff7b2e2a43c,j的地址0x7ff7b2e2a438
change3后,i的值20,j的值10,i的地址0x7ff7b2e2a43c,j的地址0x7ff7b2e2a438

可以看到i和j的地址都没有改变,值实现了互换。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容