输出星星
#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
天道酬勤