输出星星
#include <stdio.h> void printStart( int num ) { while(num-->0) { printf("*"); }; } int main() { int n = 20, i; for(i=0; i<n; i++) { printStart(i); printf("\n"); } printStart(4); return 0; }
默认情况下, C++函数按照值传递参数, 这就意味着函数中定义的形参是新的变量, C函数通过通过使用拷贝, 保护了原始数据的完整性;
虽然C语言数组名就是一个地址指针, 但是它们仍然还是按照值传递的;
如果参数是数组的话, 默认传递的是数组的复制品:
#include <stdio.h> void change(int array[2]) { array[0] = 2; } int main() { int arr[2] = {1,2}; printf("arr的第一个值是:%d\n", arr[0]); change(arr); printf("arr的第一个值是:%d\n", arr[0]); return 0; }
输出为:
arr的第一个值是:1 arr的第一个值是:2
如果参数为数组,接收的参数设置为指针, 修改指针即会修改原来的数组:
#include <stdio.h> void change(int *p) { p[0] = 2; } int main() { int arr[2] = {1,2}; printf("arr的第一个值是:%d\n", arr[0]); change(arr); printf("arr的第一个值是:%d\n", arr[0]); return 0; }
从一堆数组中找出指定的的数字:
#include <stdio.h> #define NUMBER 5 int search(int *p, int n) { int index = 0; printf("string\n"); while(true) { if(*(p+index) == n) { return index+1; } printf("%d\n", *p); index++; } return -1; } int main() { int arr[NUMBER] = {0}; int num; int i = 0; for(i=0; i<NUMBER; i++) { printf("输入索引为%d的值\n", i); scanf("%d",&arr[i]); } printf("输入需要查找的数字\n"); scanf("%d", &num); int index = search(arr, num); printf("找到的索引为%d", index); return 0; }
静态变量, 静态变量
#include <stdio.h> int foo = 0; void func() { static int sx = 0; foo++; sx++; printf("%d--%d\n", foo, sx); } int main() { func(); func(); func(); func(); return 0; }
输出:
1--1 2--2 3--3 4--4
如果声明了静态变量, 那么这个变量就会和函数挂钩, 相对于函数的属性, 静态变量只会初始化一次
数字后面不同的后缀,说明了不同的类型;
1u:unsigned int 1l:long 1ll: long long 1UL:unsigned long 0.5f:float
查看二进制数字包含1的进制位:
#include <stdio.h> int count_bit(unsigned x) { int count = 0; while(x) { if(x & 1U) count++; x >>= 1; } return count; } int main() { unsigned bits = 3; int length = count_bit(bits); printf("length is %d\n", length); return 0; }
如果数据太大, 超出了能够存储的大小, 计算结果会出现问题, 尴尬?:
#include <stdio.h> int main() { printf("int 的位数 是 %d\n", sizeof(int)); int x = 4294967296-1; int y = 333333; x += y; printf("result is %d\n", x);//输出 : result is 333332 return 0; }
又是精度问题, 使用小树会导致计算结果有误差:
#include <stdio.h> int main () { float i; for(i=0.0; i<1.0; i+=0.01) { printf("%f", i); } return 0; }
统计用户输入数字的个数:
#include <stdio.h> int main() { int count = 0; int arr[5] = {0}; while( true ) { printf("请输入数字0-4\n"); char c = getchar(); switch( c ) { case '0': arr[0]++; break; case '1': arr[1]++; break; case '2': arr[2]++; break; case '3': arr[3]++; break; case '4': arr[4]++; break; } printf("统计位数: \n 0 : %d \n 1 : %d \n 2 : %d \n 3 : %d \n 4 : %d \n", arr[0], arr[1], arr[2], arr[3], arr[4]); } return 0; }
以上的代码经过优化以后, 变成这样:
#include <stdio.h> int main() { int count = 0; int arr[5] = {0}; while( true ) { printf("请输入数字0-4\n"); char c = getchar(); if( c >= '0' && c <= '4') { printf("%d\n",c); int i = c; arr[i-48]++; } printf("统计位数: \n 0 : %d \n 1 : %d \n 2 : %d \n 3 : %d \n 4 : %d \n", arr[0], arr[1], arr[2], arr[3], arr[4]); } return 0; }
如果直接使用双引号""声明字符串, 那么字符串的最后默认会被添加一个0,作为结束标记;
#include <stdio.h> int main() { char str[] = "ABCD"; char str1[] = {'A','B','C','D'}; printf("%s ==>> %d \n", str, sizeof(str)); //长度为5 printf("%s ==>> %d \n", str1, sizeof(str1)); //长度为4, 少了一个结束位, 必须自己给上 return 0; }
字符整理成大写:
#include <stdio.h> #include <ctype.h> int main() { while(true) { char ch = getchar(); if(ch == EOF) { break; } printf("%c",toupper(ch)); } return 0; }
字符串整理成大写:
#include <stdio.h> #include <ctype.h> void up(char str[]){ int i = 0; while(str[i]) { str[i] = toupper(str[i]); i++; } } int main() { char str[10]; while(true) { scanf("%s",str); printf("you enter => %s\n", str); up(str); printf("to uppper => %s\n", str); } return 0; }
还数组和指针:
#include <stdio.h> int main() { int data[] = {22,33,44,55,66}; int *p = data; // int *p = &data[0]; 这样写也行, 因为数组中对一个数据的地址就是数组的地址; int i; for( i = 0; i < 5; i++ ) { printf("i = %d ==> %d\n", i, data[i]); printf("i = %d ==> %d\n", i, p[i]); printf("i = %d ==> %d\n", i, *(p+i)); } return 0; }
使用指针会比使用字符串数组更加灵活:
#include <stdio.h> #include <string.h> int main() { //char arr[] = "ABC"; //arr = "EDG"; //此法是不行的,arr其实是一个地址,必须这么干:strcpy(arr,"EDG"); //但是指针可以修改 char *p = "ABC"; p = "EDG"; printf("%s\n\n", p); return 0; }
指针数组 相对于 标准的数组, 更灵活, 而且存放的空间会更小:
#include <stdio.h> int main() { int data[] = {22,33,44,55,66}; int *p = data; // int *p = &data[0]; 这样写也行, 因为数组中对一个数据的地址就是数组的地址; int i; for( i = 0; i < 5; i++ ) { printf("i = %d ==> %d\n", i, data[i]); printf("i = %d ==> %d\n", i, *(p+i)); } return 0; }
如果是标准的数组, 需要给一个固定的长度, 但是使用指针数组的话, 并不会出现多余的数据, 图示:
调用函数的时候, 如果直接把结构体作为参数, 其实传递的时候结构体的副本,( 这个和js有点区别, js中对象就是是指针) 如果在函数中修改结构体, 要注意必须传递指针, 数组传递的也是副本, (除非你传递指针或者引用), 这个要注意:
#include <stdio.h> struct student{ char name[10]; int age; }; void showAge(struct student *s) { printf("%d\n",s->age); } int main() { struct student stu = {"abc", 10}; printf("%s\n", stu.name); showAge(&stu); return 0; }
以上的代码中, 我们定义了stu这个结构体, 但是 使用了比较多的的代码:
student struct stu
通过使用typedef, 可以进行简化:
#include <stdio.h> typedef struct { char name[10]; int age; } student; void showAge(student *s) { printf("%d\n",s->age); } int main() { student stu = {"abc", 10}; printf("%s\n", stu.name); showAge(&stu); return 0; }
文件读取操作的代码, 创建一个文件对象, 然后读区copy.cpp文件,通过putchar输出到控制台:
#include <stdio.h> int main () { FILE *f; int c; f = fopen("copy.cpp","r"); if(f == NULL) { printf("error\n"); }else{ while( (c=fgetc(f) )!=EOF ) { //printf("%c",c); putchar(c); } printf("open\n"); fclose(f); } return 0; }
通过描述符打开文件, 区别于fopen和FILE句柄:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <memory.h> int main() { int fd = -1; char filename[] = "fileopen.cpp"; fd = open(filename, O_RDWR); if( -1 == fd ) { printf("error\n"); }else{ printf("fd is %d\n", fd); } int size = -1; char buffer[80]; while(size) { memset(buffer, 0, sizeof(buffer)); size = read(fd, buffer, sizeof(buffer)); //printf("%s",buffer); for(int i=0 ; i<size; i++) { printf("%c",buffer[i]); } } close(fd); return 0; }
文件写入并查看:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <memory.h> int main() { int fd = -1; char filename[] = "test.txt"; fd = open(filename, O_RDWR); if( -1 == fd ) { printf("error\n"); }else{ printf("fd is %d\n", fd); } //write char str[] = "12345"; write(fd, str, sizeof(str)); //read int size = -1; char buffer[10]; fd = open(filename, O_RDWR); while(size) { memset(buffer, 0, sizeof(buffer)); size = read(fd, buffer, sizeof(buffer)); for(int i=0 ; i<size; i++) { printf("%c",buffer[i]); } } close(fd); return 0; }
给文件的固定位置添加数据, lseek :
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <unistd.h> int main() { int fd = -1, i; char buf1[] = "123456"; char buf2[] = "abcdefg"; char filename[] = "hole.txt"; fd = open(filename, O_RDWR|O_CREAT, S_IRWXU); if(fd == -1) { printf("error\n"); return 0; } int size = write(fd, buf1, sizeof(buf1)); //set offset off_t offset = lseek(fd, 32, SEEK_SET); if( -1 == offset ) { printf("error\n"); return 0; } write(fd, buf2, sizeof(buf2)); close(fd); return 0; }
获取文件的状态 stat的结构为:
struct stat { mode_t st_mode; //文件对应的模式,文件,目录等 ino_t st_ino; //inode节点号 dev_t st_dev; //设备号码 dev_t st_rdev; //特殊设备号码 nlink_t st_nlink; //文件的连接数 uid_t st_uid; //文件所有者 gid_t st_gid; //文件所有者对应的组 off_t st_size; //普通文件,对应的文件字节数 time_t st_atime; //文件最后被访问的时间 time_t st_mtime; //文件内容最后被修改的时间 time_t st_ctime; //文件状态改变时间 blksize_t st_blksize; //文件内容对应的块大小 blkcnt_t st_blocks; //伟建内容对应的块数量 };
创建结构:
#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> int main(void) { struct stat st; if(-1==stat("test.txt",&st)) { printf("get file status failure\n"); return -1; } printf("此文件的大小:%d\n",st.st_size); printf("此文件的租后修改时间:%d\n",st.st_mtime); printf("此文件的节点:%d\n",st.st_ino); printf("此文件的保护模式:%d\n",st.st_mode); }
厦门点燃未来网络科技有限公司, 是厦门最好的微信应用, 小程序, 微信网站, 公众号开发公司
EOF